# Documentazione API esterna V1

Converti le fatture in e-fatture validate direttamente dai tuoi sistemi: carica un documento PDF, DOCX o TXT – oppure dati ERP strutturati – e scarica l’output XRechnung, ZUGFeRD, EN 16931, UBL o CII una volta superata la validazione. Questa pagina è il contratto di integrazione completo: modello di accesso, endpoint, catalogo errori e limiti.

> Cinque endpoint REST trasformano fatture PDF, DOCX o TXT – o dati ERP strutturati – in e-fatture validate XRechnung, ZUGFeRD, EN 16931, UBL e CII. Gli abbonati Enterprise attivi creano le chiavi direttamente; ogni mese sono incluse 100 conversioni condivise Email/API, poi ogni conversione usa 0,50 € di crediti prepagati.

## Panoramica

L’API accetta upload multipart, restituisce risposte JSON e usa codici di stato HTTP standard con autenticazione Bearer. Ogni conversione è asincrona: invia il documento, interroga il task, scarica il risultato. Un file viene consegnato solo dopo che la validazione è stata superata: non esistono output non validati.

Invia un documento fattura PDF, DOCX o TXT oppure dati fattura strutturati a un endpoint di conversione. Invoice-Converter avvia un task asincrono per estrazione, validazione e generazione degli artefatti. L’endpoint del risultato restituisce un file solo quando l’artefatto richiesto è validato, controllato e pronto; durante l’elaborazione restituisce 202 TASK_NOT_READY, mentre i problemi di validazione bloccanti restituiscono 422 VALIDATION_FAILED.

> **Stato: accesso Enterprise**: Percorso base: /api/v1. Ultimo allineamento 2026-08-07.

## Funzionalità principali

- Endpoint di upload per fatture PDF e dati fattura strutturati
- Estrazione dei dati fattura assistita dall’IA
- Validazione automatica EN 16931 e KoSIT
- Formati di output XRechnung, ZUGFeRD, EN16931, UBL e CII
- Elaborazione asincrona con polling, fatture piccole in circa 30 secondi e fatture più grandi fino a 1-2 minuti
- Scritture idempotenti per retry sicuri

## Avvia l’accesso API Enterprise

Ogni abbonato Enterprise attivo può creare chiavi API di produzione direttamente nel profilo.

1. Crea un account e avvia Enterprise a 50 €/mese o 420 €/anno dalla pagina dei prezzi.
2. Usa le 100 conversioni condivise Email/API incluse ogni mese; le conversioni aggiuntive usano crediti prepagati a 0,50 € ciascuna.
3. Crea una chiave API live dalla sezione accesso API del profilo.
4. Esegui la prima richiesta con credenziali server-side, poi monitora l’uso e ruota le chiavi dal profilo.

## Avvia Enterprise

- [Piano Enterprise e prezzi](/pricing)

## Avvio rapido

Tre chiamate API completano una conversione. L’endpoint di conversione è servito su /api/v1 e richiede autenticazione.

### POST /api/v1/invoices:convert (Live)
Converti documento fattura

### POST /api/v1/invoices:convert-structured (Live)
Converti dati strutturati

### GET /api/v1/tasks/{task_id} (Live)
Esegui polling dello stato task

## Avvio rapido con curl

Sostituisci $API_KEY con la tua chiave live e $TASK_ID con il task_id della prima risposta. Le stesse tre chiamate valgono per ogni formato di output.

### 1. Avvia la conversione
```
curl -X POST "https://www.invoice-converter.com/api/v1/invoices:convert" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: inv-2026-0001" \
  -F "file=@invoice.pdf" \
  -F "format=XRECHNUNG"
```

### 2. Interroga il task fino a completed
```
curl "https://www.invoice-converter.com/api/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $API_KEY"
```

### 3. Scarica il file validato
```
curl -o invoice.xml \
  "https://www.invoice-converter.com/api/v1/tasks/$TASK_ID/result?download=xml" \
  -H "Authorization: Bearer $API_KEY"
```

## URL base e chiavi API

- URL di base di produzione: `https://www.invoice-converter.com/api/v1`.
- Le chiavi live usano l’host di produzione e il prefisso `icp_...`.
- Esegui richieste di onboarding e validazione con la tua chiave live prima di inviare volumi di produzione.
- Tratta le chiavi come secret server-side. Non inserirle in client browser o mobile.

## Prima richiesta riuscita

Usa questa sequenza come percorso minimo dopo aver creato una chiave API.

- Caricamento: `POST /api/v1/invoices:convert` con `Authorization`, `Idempotency-Key`, `file=@invoice.pdf` (o `.docx`/`.txt`) e `format=XRECHNUNG`.
- Esegui polling con backoff: attendi circa `20 secondi` dopo il `202`, poi chiama `GET /api/v1/tasks/{task_id}` a intervalli di 20s, 30s, 45s, 60s e 60s finché lo stato è `completed` o `failed`. Resta entro la quota di stato di `10/min` e `120/hour` e interrompi dopo circa 16 minuti.
- Scaricamento: `GET /api/v1/tasks/{task_id}/result?download=xml` e salva `X-Correlation-ID` per il tracciamento del supporto.
- Per output PDF ZUGFeRD, richiedi `format=ZUGFERD` nel convert e `download=pdf` nel result; l’output PDF ibrido richiede una sorgente PDF.
- Per input strutturato, chiama `POST /api/v1/invoices:convert-structured` con `pdf_file=@invoice.pdf`, `data_file=@invoice-data.json` e il `format` di destinazione.
- Invia opzionalmente `client_reference` o `external_invoice_id` e `source_system` per la riconciliazione ERP.
- Per export ERP divisi di una fattura, ripeti `data_file`; per più fatture, avvia un task per fattura con una propria idempotency key.
- Salva `result_artifacts` dalla risposta di stato per vedere se gli artefatti XML/PDF sono validati, in cache o ancora non disponibili per dipendenze.

## Esempi comuni di payload

- `XRECHNUNG`: invia `format=XRECHNUNG`.
- `ZUGFERD`: invia `format=ZUGFERD`; usa `download=pdf` nel result per l’output ibrido PDF/A-3.
- `Input strutturato`: invia `pdf_file` più una o più parti `data_file`; i formati dati accettati sono CSV, JSON, XML, XLSX e TXT, con qualsiasi formato di destinazione supportato. Le parti data_file devono contenere tutti i dati obbligatori; il PDF non completa i campi mancanti.
- `Più fatture`: invia richieste convert separate e traccia ogni `task_id` restituito; le parti `data_file` ripetute servono solo per export divisi della stessa fattura.
- `UBL`: invia `format=UBL`; i profili accettati sono `XRECHNUNG`, `PEPPOL` e `EN16931`, con default `EN16931`.
- `CII`: invia `format=CII`; i profili accettati sono `XRECHNUNG`, `EN16931`, `ZUGFERD_EN16931` e `ZUGFERD_XRECHNUNG`, con default `EN16931`.
- `format` x `profile` è una tabella chiusa: `XRECHNUNG` accetta `[XRECHNUNG]` (default `XRECHNUNG`), `EN16931` accetta `[EN16931]` (default `EN16931`), `UBL` accetta `[XRECHNUNG, PEPPOL, EN16931]` (default `EN16931`), `CII` accetta `[XRECHNUNG, EN16931, ZUGFERD_EN16931, ZUGFERD_XRECHNUNG]` (default `EN16931`) e `ZUGFERD` accetta `[ZUGFERD_EN16931, ZUGFERD_XRECHNUNG]` (default `ZUGFERD_EN16931`). I profili sono confrontati senza distinzione tra maiuscole e minuscole; `ZUGFERD`, `FACTURX`, `FACTUR-X` e `FACTUR_X` sono alias di `ZUGFERD_EN16931`, e `ZUGFERD-XRECHNUNG` è alias di `ZUGFERD_XRECHNUNG`.

## Header richiesti

- Authorization: Bearer <api_key>

## Regole di autenticazione

Ogni abbonato Enterprise attivo può creare chiavi API dal profilo e usarle come Bearer token. La quota condivisa Email/API comprende 100 conversioni al mese; le conversioni aggiuntive usano crediti prepagati a 0,50 € ciascuna.

- Le chiavi sono credenziali live scoped per tenant per abbonamenti Enterprise attivi. Il prefisso di produzione corrente è `icp_...`.
- Crea, ruota e revoca le chiavi API dal profilo mentre Enterprise è attivo. Copia subito le nuove chiavi perché il valore in chiaro viene mostrato una sola volta.
- Chiave mancante o non valida restituisce `401`.
- Le chiamate a `/api/v1` ricevono automaticamente `X-Correlation-ID` se omesso.
- Le chiamate di scrittura richiedono `Idempotency-Key`; mantieni stabile questo valore nei retry.
- Usa integrazione server-to-server dal tuo backend. L’accesso da browser-origin è limitato in produzione.

## Contratto di idempotenza

- Invia un `Idempotency-Key` a ogni chiamata di scrittura.
- Le chiavi di idempotenza devono corrispondere a `[A-Za-z0-9._:-]+` ed essere lunghe al massimo 200 caratteri.
- Se fornisci una tua chiave, stessa chiave + payload identico restituisce la risposta in cache.
- Stessa chiave + payload diverso restituisce `409 IDEMPOTENCY_CONFLICT`, che non è ripetibile; usa una nuova chiave per un nuovo payload.
- Una seconda richiesta con la stessa chiave mentre la prima è ancora in elaborazione restituisce `409 IDEMPOTENCY_IN_PROGRESS`; riprova con la stessa chiave dopo una breve attesa. Una prenotazione bloccata viene rilasciata dopo `15 minuti`.
- Se il task originale ha superato la ritenzione di 24 ore, un replay restituisce `409 IDEMPOTENCY_REPLAY_EXPIRED`; avvia una nuova conversione con una nuova chiave.
- I record di idempotenza vivono `24 ore`, in linea con la ritenzione dei task.

## Riferimento endpoint

Tutti gli endpoint sono disponibili su /api/v1. I timeout emergono come 504 e altri errori temporanei di connettività come 502; gli ID di correlazione aiutano il supporto a seguire le richieste end-to-end.

### POST /api/v1/invoices:convert (Live)
Carica un documento fattura PDF, DOCX o TXT e avvia la conversione asincrona. Restituisce un task_id per il polling. I download PDF ibridi ZUGFeRD/Factur-X richiedono una sorgente PDF; per sorgenti DOCX/TXT richiedere risultati XML. Richiesta: multipart/form-data; file (binary, obbligatorio) — documento sorgente fattura PDF, DOCX o TXT; i vecchi DOC/RTF, immagini e altri file sono rifiutati; format (string, obbligatorio) — formato di output target; vedere la matrice dei formati sotto; profile (string, opzionale, consigliato per integrazioni deterministiche) — profilo di conformità esplicito, confrontato senza distinzione tra maiuscole e minuscole. Ogni formato ha un insieme chiuso di valori accettati e un solo default: XRECHNUNG → [XRECHNUNG] (default XRECHNUNG); EN16931 → [EN16931] (default EN16931); UBL → [XRECHNUNG, PEPPOL, EN16931] (default EN16931); CII → [XRECHNUNG, EN16931, ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (default EN16931); ZUGFERD → [ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (default ZUGFERD_EN16931). ZUGFERD, FACTURX, FACTUR-X e FACTUR_X sono alias di ZUGFERD_EN16931; ZUGFERD-XRECHNUNG è alias di ZUGFERD_XRECHNUNG. Un valore fuori dall’insieme accettato restituisce 422 OUTPUT_PROFILE_CONFLICT; un nome di profilo non riconosciuto restituisce 422 INVALID_PROFILE con details.allowed_profiles; jurisdiction (string, opzionale) — contesto di giurisdizione ISO 3166-1 alpha-2 esplicito usato per controlli di validazione/avviso; non sovrascrive il profilo; transaction_scope (string, opzionale) — contesto esplicito dell’ambito transazionale, ad esempio B2G; applicato al task in coda; delivery_channel (string, opzionale) — uno tra PEPPOL, DIRECT_XML, PORTAL, EMAIL_PDF, UNKNOWN; applicato al task in coda; client_reference o external_invoice_id (string, opzionale) — riferimento fattura/job lato cliente restituito negli upload accettati e nelle risposte di stato task; source_system (string, opzionale) — etichetta dell’ERP o sistema di fatturazione upstream restituita negli upload accettati e nelle risposte di stato task; use_seller_master_data (boolean, opzionale) — se omesso vale il default del profilo tenant; false ignora i dati anagrafici venditore salvati per questa richiesta, true fornisce/usa i dati anagrafici venditore; seller_master_data (stringa oggetto JSON, opzionale) — dati venditore usati solo quando use_seller_master_data=true; supporta campi aziendali, indirizzo, fiscali, contatto e pagamento (payment_means_code 30/42/58, payment_iban, payment_bic, payment_account_name, payment_terms_note); ogni valore del profilo sostituisce il corrispondente valore estratto, i campi assenti dal profilo restano invariati e le differenze generano avvisi non bloccanti. Risposta: 202 Accepted.

### POST /api/v1/invoices:convert-structured (Live)
Carica un PDF contenitore con dati fattura CSV, JSON, XML, XLSX o TXT e avvia la conversione asincrona da dati strutturati. Le parti data_file sono l’unica fonte semantica; il PDF non completa i campi fattura mancanti. Per ZUGFeRD/Factur-X viene usato come PDF contenitore, mentre per output orientati a XML viene conservato come artefatto PDF inviato. Usa una richiesta di conversione per fattura; ripeti data_file solo per export ERP divisi che descrivono la stessa fattura. Richiesta: multipart/form-data; pdf_file (binary, obbligatorio) — PDF contenitore usato per l’incorporamento ZUGFeRD/Factur-X e conservato per output orientati a XML; data_file (binary, obbligatorio, ripetibile) — dati fattura CSV, JSON, XML, XLSX o TXT usati come unica fonte semantica; .xls, PDF e file immagine sono rifiutati come data_file; ripeti per export header/righe divisi della stessa fattura; gli alias data_files e data_files[] sono accettati; dimensione totale dati strutturati — massimo 2 MB su tutte le parti data_file; format (string, obbligatorio) — formato output di destinazione; supporta XRECHNUNG, ZUGFERD, EN16931, UBL e CII; profile (string, opzionale, consigliato per integrazioni deterministiche) — profilo di conformità esplicito, confrontato senza distinzione tra maiuscole e minuscole. Ogni formato ha un insieme chiuso di valori accettati e un solo default: XRECHNUNG → [XRECHNUNG] (default XRECHNUNG); EN16931 → [EN16931] (default EN16931); UBL → [XRECHNUNG, PEPPOL, EN16931] (default EN16931); CII → [XRECHNUNG, EN16931, ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (default EN16931); ZUGFERD → [ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (default ZUGFERD_EN16931). Un valore fuori dall’insieme accettato restituisce 422 OUTPUT_PROFILE_CONFLICT; un nome di profilo non riconosciuto restituisce 422 INVALID_PROFILE con details.allowed_profiles; jurisdiction (string, opzionale) — contesto di giurisdizione ISO 3166-1 alpha-2 esplicito usato per controlli di validazione/avviso; non sovrascrive il profilo; transaction_scope (string, opzionale) — contesto esplicito dell’ambito transazionale, ad esempio B2G; applicato al task in coda; delivery_channel (string, opzionale) — uno tra PEPPOL, DIRECT_XML, PORTAL, EMAIL_PDF, UNKNOWN; applicato al task in coda; client_reference o external_invoice_id (string, opzionale) — riferimento fattura/job lato cliente restituito negli upload accettati e nelle risposte di stato task; source_system (string, opzionale) — etichetta dell’ERP o sistema di fatturazione upstream restituita negli upload accettati e nelle risposte di stato task; use_seller_master_data (boolean, opzionale) — se omesso vale il default del profilo tenant; false ignora i dati anagrafici venditore salvati per questa richiesta, true fornisce/usa i dati anagrafici venditore; seller_master_data (stringa oggetto JSON, opzionale) — dati venditore usati solo quando use_seller_master_data=true; supporta campi aziendali, indirizzo, fiscali, contatto e pagamento (payment_means_code 30/42/58, payment_iban, payment_bic, payment_account_name, payment_terms_note); ogni valore del profilo sostituisce il corrispondente valore estratto, i campi assenti dal profilo restano invariati e le differenze generano avvisi non bloccanti. Risposta: 202 Accepted.

### GET /api/v1/tasks/{task_id} (Live)
Esegui il polling dello stato corrente di un task di conversione. Restituisce pending (accettato e in coda, non ancora avviato), processing, completed o failed. Rate limit 10/min e 120/hour: è il vincolo determinante per il polling: attendi circa 20 secondi dopo il 202 accettato prima della prima chiamata, poi distanzia le chiamate (20s, 30s, 45s, 60s e da lì 60s) e fermati su completed o failed. I task completati includono diagnostica `result_artifacts`, così i client possono vedere quali artefatti XML/PDF sono disponibili, in cache e provati dalla validazione. I payload dei task completati possono includere voci aggiuntive `_processing_warnings` e `_validation_warnings` con ID delle regole SOURCE_CONTEXT_* quando le evidenze della fonte erano indisponibili, sospette o troncate; trattale come segnali di revisione, non come errori. Quando è failed, la risposta include un campo error con il motivo dell’errore. Richiesta: nessuno (GET); task_id (path, obbligatorio) — UUID restituito dall’endpoint di conversione; include_validation_report_html (query, opzionale) — true o false (default false); con true la risposta di stato include il report di validazione HTML sanificato dell’artefatto rigoroso corrente quando disponibile. Risposta: 200 OK.

### GET /api/v1/tasks/{task_id}/result (Live)
Scarica il file generato (XML o PDF). La sintassi del risultato corrisponde al formato originale del task: XRECHNUNG/EN16931/UBL restituiscono UBL XML, CII/ZUGFERD restituiscono CII XML, e ZUGFERD + download=pdf restituisce un PDF/A-3 ibrido. Per altri formati, download=pdf può restituire un PDF renderizzato; su un task completato download=xml è l’artefatto atteso come disponibile, non garantito. Download ripetuti possono essere serviti da artefatti generati in cache quando la prova di validazione è ancora attuale. Durante l’elaborazione questo endpoint restituisce un 202 con l’envelope di errore standard ({"code":"TASK_NOT_READY","message":"Strict conversion is still processing. No validated artifact is available yet.","correlation_id":"<uuid>"}); i problemi di validazione bloccanti restituiscono 422 VALIDATION_FAILED, le dipendenze non disponibili ma ripetibili restituiscono 503, i fallimenti di conversione definitivi restituiscono 500 TASK_FAILED con il motivo in details.code e i fallimenti degli invarianti degli artefatti restituiscono 500 INTERNAL_ARTIFACT_INVARIANT_FAILED, sempre senza corpo file. I download riusciti riportano X-Correlation-ID, Content-Disposition, Cache-Control: no-store, X-Artifact-Sha256, X-Validation-Proof-Id, X-Artifact-Proof-Id, X-Artifact-State, X-Validation-State, X-Proof-Status e X-Validator-Bundle-Id; X-Task-Id non è impostato su questo endpoint. Rate limit 10/min e circa 134/hour. Richiesta: nessuno (GET); task_id (path, obbligatorio) — UUID restituito dall’endpoint di conversione; download (query, obbligatorio) — xml o pdf. Risposta: 200 OK.

### GET /api/v1/tasks/{task_id}/validation-report (Live)
Download the validation report tied to the current validated result artifact. The report is available only after strict conversion has produced a cached artifact with current validation proof, and returns 404 when no report is bound to the delivered artifact. A 202 carries the standard TASK_NOT_READY error envelope, not a file body. Successful responses carry X-Correlation-ID, Content-Disposition, Cache-Control: no-store, X-Artifact-Sha256, X-Validation-Proof-Id, X-Artifact-Proof-Id, X-Artifact-State, X-Validation-State, X-Proof-Status, X-Validator-Bundle-Id, plus X-Task-Id, X-Validation-Report-Proof-Id, X-Validation-Report-Content-Type, X-Validation-Report-Format, X-Validation-Report-Source, and X-Report-Source-Artifact-Format. Those artifact-level diagnostics describe the validated result artifact the report covers, not the returned report bytes: X-Artifact-Sha256 is the SHA-256 of that source artifact and must not be used to checksum the downloaded report, while X-Validation-Report-Proof-Id identifies the proof that supplied the report payload. Rate limit 10/min and 120/hour. Richiesta: none (GET); task_id (path, required) — UUID returned by the convert endpoint; download (query, optional) — html or xml. Risposta: 200 OK.

## Matrice dei formati di output

| Formato | Sintassi | Versione / Profilo | Content-Type | Estensione |
| --- | --- | --- | --- | --- |
| XRECHNUNG | UBL 2.1 XML | XRechnung 3.0.2 | application/xml | .xml |
| ZUGFERD | CII XML (download=xml) / PDF/A-3 ibrido (download=pdf) | ZUGFeRD 2.3.2 / Factur-X 1.07.2 | application/xml o application/pdf | .xml / .pdf |
| EN16931 | UBL 2.1 XML | EN 16931 | application/xml | .xml |
| UBL | UBL 2.1 XML | OASIS UBL 2.1 | application/xml | .xml |
| CII | UN/CEFACT CII XML | D16B | application/xml | .xml |

## Contratto errori

| Codice | HTTP | Ripetibile | Note |
| --- | --- | --- | --- |
| AUTHENTICATION_REQUIRED | 401 | No | Bearer token mancante/vuoto |
| INVALID_API_KEY | 401 | No | Chiave API non trovata, revocata o scaduta |
| API_NOT_ENABLED_FOR_TENANT | 403 | No | Key is valid but External API access is not enabled for the account; contact support instead of retrying |
| INSUFFICIENT_API_CREDITS | 402 | No | La quota mensile inclusa più i crediti API prepagati non coprivano la richiesta. Due forme di details: prepagato (remaining, minimum_purchase 100) e quota inclusa (included_remaining, credit_remaining, shortfall, minimum_purchase 100). Analizza il code e leggi le chiavi effettivamente presenti |
| IDEMPOTENCY_KEY_REQUIRED | 400 | No | Endpoint di scrittura chiamato senza Idempotency-Key |
| INVALID_IDEMPOTENCY_KEY | 400 | No | La chiave di idempotenza deve corrispondere a [A-Za-z0-9._:-]+ ed essere lunga al massimo 200 caratteri |
| IDEMPOTENCY_CONFLICT | 409 | No | La chiave è già stata usata con un payload diverso, oppure la prenotazione idempotente non è stata avviata; usa una nuova chiave per un nuovo payload |
| IDEMPOTENCY_IN_PROGRESS | 409 | Sì | La prima richiesta con questa chiave è ancora in elaborazione; riprova con la STESSA chiave dopo una breve attesa. Una prenotazione bloccata viene rilasciata dopo 15 minuti |
| IDEMPOTENCY_REPLAY_EXPIRED | 409 | No | The original task is past its 24-hour retention and cannot be recovered; start a new conversion with a new key |
| FORMAT_REQUIRED | 400 | No | Richiesta di conversione senza il format obbligatorio |
| INVALID_FORMAT | 422 | No | Formato di conversione non supportato |
| CLIENT_REFERENCE_CONFLICT | 400 | No | client_reference ed external_invoice_id sono diversi |
| INVALID_CLIENT_METADATA | 400 | No | client_reference, external_invoice_id o source_system supera il limite di lunghezza o contiene caratteri di controllo |
| INVALID_SELLER_MASTER_DATA | 400 | No | use_seller_master_data o seller_master_data non è analizzabile o non supera la validazione dei campi |
| METHOD_NOT_ALLOWED | 405 | No | I percorsi di conversione accettano solo POST e i percorsi task solo GET; la risposta include Allow: POST, OPTIONS (conversione) oppure Allow: GET, OPTIONS (task) |
| DOWNLOAD_FORMAT_REQUIRED | 400 | No | Richiesta task-result senza la query download obbligatoria |
| INVALID_DOWNLOAD_FORMAT | 400 | No | La query download del task-result deve essere xml o pdf |
| AUTH_SERVICE_UNAVAILABLE | 503 | Sì | Backend auth non disponibile |
| RATE_LIMIT_SERVICE_UNAVAILABLE | 503 | Sì | Non è stato possibile raggiungere il servizio di rate-limit; riprova con backoff |
| PLAN_TIER_CHECK_FAILED | 503 | Sì | Plan/API access could not be verified right now; retry with backoff |
| API_CREDIT_SERVICE_UNAVAILABLE | 503 | Sì | La verifica dei crediti API prepagati o della quota canale è temporaneamente non disponibile sugli upload di conversione |
| RATE_LIMITED | 429 | Sì | Rispettare Retry-After. Retry-After, X-RateLimit-Limit-Minute e X-RateLimit-Limit-Hour vengono restituiti solo sulle risposte 429; il body riporta details.minute_count, details.hour_count, details.limit_minute e details.limit_hour |
| BAD_REQUEST | 400 | No | JSON non valido o parametro path UUID non valido |
| INVALID_QUERY_PARAMETER | 400 | No | include_validation_report_html deve essere true o false |
| PAYLOAD_TOO_LARGE | 413 | No | Oltre il limite dimensione upload |
| INVALID_UPLOAD | 400 | No | Lettura/parsing upload non riusciti |
| UPLOAD_FAILED | 422 | No | Un campo di contesto opzionale (jurisdiction, transaction_scope, delivery_channel) conteneva un valore non riconosciuto; i valori consentiti sono indicati nel message |
| INVALID_PROFILE | 422 | No | The value is not a recognized profile name; details.allowed_profiles lists the accepted set |
| TASK_NOT_READY | 202 | Sì | Eseguire di nuovo polling per completamento async |
| TASK_NOT_FOUND | 404 | No | Il task è sconosciuto, non appartiene al tenant oppure ha superato la ritenzione di 24 ore dopo aver raggiunto uno stato terminale |
| VALIDATION_FAILED | 422 | No | Restano problemi di validazione bloccanti, inclusi i fallimenti dei prerequisiti rigorosi ZUGFeRD e le voci blocking_source_conflict non risolte; correggi i dati fattura prima di riprovare |
| AUTHORITATIVE_VALIDATION_UNAVAILABLE | 503 | Sì | Validazione autorevole, persistenza della prova o dipendenza di generazione ibrida non disponibile; riprova più tardi |
| TASK_STATUS_FAILED | 4xx/5xx | Condizionale | Retry se la condizione del servizio è transitoria |
| TASK_RESULT_FAILED | 4xx/5xx | Condizionale | Retry se la condizione del servizio è transitoria |
| TASK_FAILED | 500 | Condizionale | Fallimento di conversione segnalato sull’endpoint di risultato. Leggi details.code e details.retryable: MULTIPLE_INVOICES_IN_DOCUMENT, NO_INVOICE_DETECTED, INSUFFICIENT_INVOICE_SIGNAL, SCHEMA_PARSE_FAILED e ARTIFACT_PARITY_FAILED sono definitivi; PROVIDER_ERROR e qualunque details.code non riconosciuto seguono details.retryable, e details.retryable=true significa avviare una NUOVA conversione con una nuova Idempotency-Key invece di ripetere il polling dello stesso task. La conversione fallita non consuma un’unità di fatturazione |
| MULTIPLE_INVOICES_IN_DOCUMENT | 500 (details code) | No | Terminal: the source document contains more than one invoice, corroborated by distinct invoice identifiers or a reported invoice count. details.retryable and details.can_review are false. Split the PDF into one file per invoice and start a separate conversion for each invoice |
| NO_INVOICE_DETECTED | 500 (details code) | No | Terminal: the document does not look like an invoice. Route to human handling |
| INSUFFICIENT_INVOICE_SIGNAL | 500 (details code) | No | Terminal: not enough invoice data for reliable extraction. Supply a better source document or use structured conversion |
| SCHEMA_PARSE_FAILED | 500 (details code) | No | Terminal for that input: extraction returned a payload that failed schema parsing. Start a new conversion; escalate if it repeats on the same document |
| PROVIDER_ERROR | 500 (details code) | Condizionale | Extraction-provider failure; details.retryable is authoritative. When details.classification is provider_context_too_large, use a smaller source document |
| XML_GENERATION_FAILED | 500 | Sì | Errore transitorio di generazione XML o timeout |
| PDF_GENERATION_FAILED | 500 | Sì | Errore transitorio di generazione PDF o timeout |
| ARTIFACT_GENERATION_RERUN_REQUIRED | 503 | No | Generazione artifact rigorosa non riuscita dopo i retry server-side; avvia una nuova conversione dopo il ripristino della dipendenza |
| EXTRACTION_INCOMPLETE_GROUP_FAILURE | 503 | No | Extraction finished with one or more failed field groups. The same task will not recover: start a NEW conversion. details carries type "dependency", dependency "parallel_extraction", stage "extraction", retryable true, same_task_retryable false, recovery "start_new_conversion", and failed_groups |
| ARTIFACT_GENERATION_FAILED | 503 (details code) | No | Registrato sui task falliti per errori di emissione rigorosa ritentabili; i download del risultato restituiscono 503 ARTIFACT_GENERATION_RERUN_REQUIRED con questo codice in details |
| ARTIFACT_PARITY_FAILED | 500 (details code) | No | Segnalato nei details di 500 TASK_FAILED quando l’artefatto rigoroso non corrisponde ai dati fattura finali revisionati; effettua l’escalation con l’ID di correlazione |
| INTERNAL_ARTIFACT_INVARIANT_FAILED | 500 | No | Il task rigoroso completato non ha un artefatto memorizzato sicuro per il download richiesto; effettua l’escalation con l’ID di correlazione |
| PROFILE_MISMATCH | 422 | No | Il profilo richiesto non corrisponde al CustomizationID del risultato memorizzato durante il download del risultato |
| ZUGFERD_SOURCE_PDF_INCOMPATIBLE | 422 | No | La generazione PDF ibrida rigorosa non può incorporare l’XML nel PDF sorgente caricato |
| ZUGFERD_SOURCE_PDF_REQUIRED | 422 | No | download=pdf per ZUGFERD richiede una sorgente PDF (le sorgenti DOCX/TXT non possono trasportare il PDF ibrido); richiedi invece download=xml |
| VALIDATION_REPORT_NOT_FOUND | 404 | No | Nessun report di validazione è legato alla prova dell’artefatto attualmente consegnato |
| VALIDATION_REPORT_FAILED | 4xx/5xx | Condizionale | Recupero del report di validazione non riuscito; retry solo per casi 5xx transitori |
| OUTPUT_PROFILE_REQUIRED | 422 | No | Un endpoint o contesto di richiesta correlato richiede un profilo esplicito per un contratto di output generico |
| OUTPUT_PROFILE_CONFLICT | 422 | No | Il profilo contraddice il formato di output selezionato o la variante esplicita |
| PROXY_ERROR | 502/504 | Sì | Errore di trasporto e non esito di conversione: fallimento proxy/upstream (504 per timeout). Riprova con backoff e la stessa idempotency key |

## Errori comuni e cosa fare

- Riprova con backoff: `429`, `502`, `504`, `503` con un codice ripetibile e i `500` transitori che non siano `TASK_FAILED` o `INTERNAL_ARTIFACT_INVARIANT_FAILED`. `500 TASK_FAILED` è ripetibile solo quando `details.retryable` è `true`, e solo come nuova conversione.
- Non riprovare: `400`, `401`, `402`, `403`, `404`, `405`, `413`, `422`, `409 IDEMPOTENCY_CONFLICT`, `409 IDEMPOTENCY_REPLAY_EXPIRED`, `500 TASK_FAILED` quando `details.retryable` non è `true`, e `500 INTERNAL_ARTIFACT_INVARIANT_FAILED`.
- Correggi request o dati sorgente: `400`, `413`, `422`.
- Correggi accesso o credenziali: `401 INVALID_API_KEY`. `403 API_NOT_ENABLED_FOR_TENANT` significa che la chiave è valida ma l’accesso External API non è abilitato per l’account — contatta il supporto.
- Verifica la quota mensile inclusa o acquista un pacchetto di crediti API prepagati: `402 INSUFFICIENT_API_CREDITS`. Leggi le chiavi `details` effettivamente presenti (`remaining` per gli account prepagati, oppure `included_remaining`/`credit_remaining`/`shortfall` quando si applica una quota inclusa).
- Continua il polling più tardi: `202 TASK_NOT_READY`.
- Per `500 TASK_FAILED`, leggi `details.code` e `details.retryable`. `MULTIPLE_INVOICES_IN_DOCUMENT`, `NO_INVOICE_DETECTED`, `INSUFFICIENT_INVOICE_SIGNAL`, `SCHEMA_PARSE_FAILED` e `ARTIFACT_PARITY_FAILED` sono definitivi; `PROVIDER_ERROR` e qualunque codice non riconosciuto seguono `details.retryable`, e `true` significa avviare una NUOVA conversione invece di ripetere il polling dello stesso task. Una conversione fallita non consuma un’unità di fatturazione.
- Per `422 VALIDATION_FAILED`, mostra il campo, l’ID della regola e la correzione proposta a una persona incaricata della revisione prima di riprovare con dati fattura corretti.
- Per `503 AUTHORITATIVE_VALIDATION_UNAVAILABLE`, recupera più tardi lo stesso risultato task; non è stato consegnato alcun artefatto non verificato. Per `503 ARTIFACT_GENERATION_RERUN_REQUIRED` e `503 EXTRACTION_INCOMPLETE_GROUP_FAILURE`, avvia invece una nuova conversione.
- `502` e `504 PROXY_ERROR` sono errori di trasporto e non esiti di conversione; riprova con backoff e la stessa idempotency key.

## Limiti di frequenza e payload

Rate limit per chiave e vincoli di dimensione payload si applicano a tutte le chiamate API. Le conversioni rifiutate non consumano crediti API prepagati; i rate limit sono calcolati separatamente per endpoint.

- I limiti per endpoint sono ponderati per costo e ogni endpoint ha il proprio bucket, così il polling non può esaurire la capacità di conversione. Default per chiave API: `POST /invoices:convert` e `POST /invoices:convert-structured` `30/min` e `500/hour`; `GET /tasks/{task_id}` `10/min` e `120/hour`; `GET /tasks/{task_id}/result` `10/min` e circa `134/hour`; `GET /tasks/{task_id}/validation-report` `10/min` e `120/hour`.
- Gli header di quota sono restituiti solo sulle risposte `429 RATE_LIMITED`. Le risposte riuscite non riportano header di quota: considera la tabella sopra come il contratto operativo e leggi i valori effettivi esatti da una risposta `429`.
- Il bucket di stato è il vincolo determinante per il polling: attendi circa `20 secondi` dopo il `202` accettato prima della prima chiamata di stato, poi distanzia le chiamate (20s, 30s, 45s, 60s e da lì 60s) e fermati su `completed` o `failed`. Non fare polling ogni 10 secondi; un singolo task interrogato così consuma tutto il budget orario in 20 minuti.
- Dimensione massima upload documento sorgente: `20 MB` per file PDF, DOCX o TXT.
- Dimensione massima upload dati strutturati: `2 MB` totali su tutte le parti `data_file`.
- Dimensione massima payload JSON: `1 MB`
- Le risposte `429` includono `Retry-After`, `X-RateLimit-Limit-Minute` e `X-RateLimit-Limit-Hour`, oltre a `details.minute_count`, `details.hour_count`, `details.limit_minute` e `details.limit_hour`.

## Guida ai tentativi

- Usa backoff esponenziale con jitter e riusa la stessa `Idempotency-Key` a ogni retry di una richiesta di scrittura.
- Decidi in base al `code` leggibile da macchina — e a `details.code` più `details.retryable` per `500 TASK_FAILED` — mai in base al solo stato HTTP. In questa API un `500` non è automaticamente ripetibile.
- Ripetibili: `429`, `502`, `504`, `503` con un codice ripetibile, i `500` transitori che NON siano `TASK_FAILED` o `INTERNAL_ARTIFACT_INVARIANT_FAILED`, e `500 TASK_FAILED` quando `details.retryable` è `true` (fallimenti provider transitori: rate limit, timeout, errore di trasporto) — ripeti quel caso come NUOVA conversione con una nuova `Idempotency-Key`, non ripetendo il polling dello stesso task.
- Mai ripetere: `400`, `401`, `402`, `403`, `404`, `405`, `413`, `422`, `409 IDEMPOTENCY_CONFLICT`, `409 IDEMPOTENCY_REPLAY_EXPIRED`, `500 TASK_FAILED` quando `details.retryable` non è `true`, e `500 INTERNAL_ARTIFACT_INVARIANT_FAILED`. Una conversione fallita in modo definitivo non consuma un’unità di fatturazione.
- `409 IDEMPOTENCY_IN_PROGRESS` è ripetibile con la STESSA chiave dopo una breve attesa; una prenotazione bloccata viene rilasciata dopo 15 minuti.
- `503 ARTIFACT_GENERATION_RERUN_REQUIRED` e `503 EXTRACTION_INCOMPLETE_GROUP_FAILURE` richiedono una NUOVA conversione invece di un retry dello stesso task.

## Ciclo di vita del task e conservazione

- Un task e i suoi artefatti memorizzati sono conservati per `24 ore` dopo che il task raggiunge uno stato terminale (`completed` o `failed`), poi vengono eliminati. Dopo l’eliminazione, le richieste di stato, risultato e report di validazione restituiscono `404 TASK_NOT_FOUND`.
- Non esiste un timeout di conversione fisso. Un task fallisce dopo una finestra di stallo di `5 minuti` senza aggiornamenti di fase o avanzamento, oppure quando l’elaborazione totale supera il tetto assoluto di `15 minuti`.
- Imposta il timeout lato client a circa `16 minuti` dal `202` accettato. La maggior parte delle conversioni si completa ben sotto i due minuti.
- I record di idempotenza vivono `24 ore`, in linea con la ritenzione dei task. Una richiesta bloccata in elaborazione viene rilasciata dopo `15 minuti`.
- I contatori rate-limit si azzerano su una finestra mobile.

## Modello di supporto

- Supporto in orario lavorativo con sforzi commercialmente ragionevoli.
- Nessuno SLA formale, credito di servizio o impegno sui tempi di risposta salvo accordo in un order form.

## Registro modifiche

Modifiche API esterne più recenti.

### 2026-08-07
Documentation release 1.13.0: Enterprise is available through direct checkout for EUR 50 per month or EUR 420 per year. Every active Enterprise subscription includes 100 conversion units per month shared by Email Import and External API V1; additional units use prepaid credits at EUR 0.50 each. Email Import and External API V1 no longer require manual account approval. Email Import still requires profile enablement and a verified sender.

### 2026-07-29
Documentation release 1.12.0. No runtime behavior changed on this date; these entries document behavior that was already live. MULTIPLE_INVOICES_IN_DOCUMENT is now published in the error catalog. It is returned as 500 TASK_FAILED with details.code=MULTIPLE_INVOICES_IN_DOCUMENT, details.retryable=false, and details.can_review=false. It is terminal: split the source into one document per invoice. The failed attempt does not consume a billing unit. Retry guidance corrected: a 500 is not automatically retryable. Branch on code, and on details.code plus details.retryable for 500 TASK_FAILED, instead of on the HTTP status alone. Treat 500 TASK_FAILED as terminal unless details.retryable is true (transient provider failures such as rate limiting, timeouts, and transport errors), in which case start a new conversion with a new Idempotency-Key rather than re-polling the same task. Never retry 500 INTERNAL_ARTIFACT_INVARIANT_FAILED. Billing is documented as included-allowance-then-credits, so 402 INSUFFICIENT_API_CREDITS has two details shapes: prepaid (remaining, minimum_purchase) and included allowance (included_remaining, credit_remaining, shortfall, minimum_purchase). Newly documented runtime error codes that were already being returned: 403 API_NOT_ENABLED_FOR_TENANT, 409 IDEMPOTENCY_IN_PROGRESS, 409 IDEMPOTENCY_REPLAY_EXPIRED, 422 INVALID_PROFILE, 422 UPLOAD_FAILED, 400 INVALID_IDEMPOTENCY_KEY, 503 PLAN_TIER_CHECK_FAILED, 503 RATE_LIMIT_SERVICE_UNAVAILABLE, and 503 EXTRACTION_INCOMPLETE_GROUP_FAILURE. The 409 class is split by retry semantics: IDEMPOTENCY_IN_PROGRESS is retryable with the same key after a short delay, while IDEMPOTENCY_CONFLICT and IDEMPOTENCY_REPLAY_EXPIRED require a new key. Validation-report header passthrough fixed, and X-Validation-Report-Format, X-Validation-Report-Source, and X-Report-Source-Artifact-Format are now published. On the validation-report endpoint, X-Artifact-Sha256 is the SHA-256 of the result artifact the report validates, not of the returned report bytes; X-Validation-Report-Proof-Id identifies the proof that supplied the report payload. Added retention and lifecycle statements: 24-hour task/artifact retention after a terminal state, 24-hour idempotency records, a 15-minute in-progress reclaim, a 5-minute stall window, a 15-minute hard cap, and a recommended ~16-minute client timeout. Rate limits and polling guidance replaced with per-endpoint numbers, including the previously missing validation-report bucket. Quota headers are returned on 429 responses only, and the former "poll every 10-15 seconds" advice is replaced with a first-poll delay plus backoff. Published a closed format x profile compatibility table with the default profile for each format, and corrected download=xml on a completed task from "always available" to expected-available. Corrected 405 METHOD_NOT_ALLOWED to return Allow: POST, OPTIONS on conversion paths and Allow: GET, OPTIONS on task paths, and corrected 422 PROFILE_MISMATCH: there is no profile query parameter, and the fix is to start a new conversion with an aligned profile.

### 2026-07-28
External API conversions now run the same document-scope gate as the interactive product, including on forced extraction modes that previously skipped it. A source document whose extraction reports multiple invoices, corroborated by two or more distinct invoice identifiers or by an invoice count with no identifiers, now fails terminally with MULTIPLE_INVOICES_IN_DOCUMENT. The failure is not retryable: split the source into one document per invoice and submit each separately. An uncorroborated multiple_invoices verdict no longer fails the conversion. On strict API issuance it returns 422 VALIDATION_FAILED with a blocking_source_conflict issue entry, which covers duplicate renditions such as an original plus its copy, a reprint, or a second-language rendition.

### 2026-07-26
When seller master data is enabled, every supplied profile value replaces the corresponding extracted seller or payment value. Fields absent from the profile remain unchanged. Source differences are non-blocking review warnings.

### 2026-07-25
Superseded by the 2026-07-26 entry above. Seller master data filled missing seller and payment fields only; explicit invoice values remained unchanged, and material profile/source conflicts blocked strict issuance until review. Since 2026-07-26 every supplied profile value replaces the corresponding extracted value instead.

### 2026-07-10
Recupero di documentazione; nessuna modifica al comportamento a runtime. Il catalogo errori ora documenta codici di errore runtime prima non documentati, tra cui API_CREDIT_SERVICE_UNAVAILABLE, TASK_NOT_FOUND, INVALID_CLIENT_METADATA, INVALID_SELLER_MASTER_DATA, PROFILE_MISMATCH, ZUGFERD_SOURCE_PDF_REQUIRED, VALIDATION_REPORT_NOT_FOUND, VALIDATION_REPORT_FAILED, INVALID_QUERY_PARAMETER e METHOD_NOT_ALLOWED. I client che analizzano le risposte di errore tramite il campo code leggibile da macchina non richiedono modifiche; i client basati su un elenco fisso di codici devono aggiungere i valori appena documentati. Date del changelog corrette: il supporto per sorgenti DOCX/TXT è stato rilasciato il 2026-06-30, non il 2026-07-06.

### 2026-07-06
I payload dei task completati possono includere voci aggiuntive _processing_warnings e _validation_warnings con ID delle regole SOURCE_CONTEXT_* quando le evidenze della fonte erano indisponibili, sospette o troncate prima dell’estrazione. Tratta le voci SOURCE_CONTEXT_* come segnali di revisione per la gestione delle eccezioni lato cliente; i download di artefatti rigorosi restano governati dalla prova di validazione e dai controlli sugli artefatti.

### 2026-07-03
I fallimenti dei prerequisiti rigorosi ZUGFeRD (campi obbligatori mancanti per la generazione ibrida) ora falliscono come 422 VALIDATION_FAILED con gli ID delle regole bloccanti invece di un 503 ritentabile; indirizzali a un flusso di correzione dati, non a un ciclo di retry. Per i formati solo XML (XRECHNUNG, EN16931, UBL, CII) il rendering PDF è ora un artefatto di comodità best effort: download=xml resta autorevole e disponibile sui task completati, mentre download=pdf può risultare non disponibile se il rendering è fallito dopo l’emissione dell’XML. Le conversioni con conflitti di fonte bloccanti non risolti ora falliscono come 422 VALIDATION_FAILED con voci blocking_source_conflict invece di emettere un artefatto.

### 2026-06-30
POST /api/v1/invoices:convert ora accetta documenti sorgente fattura PDF, DOCX e TXT nel campo file. I vecchi file DOC, RTF, immagini e altre sorgenti non supportate sono rifiutati prima dell’avvio della conversione. I download PDF ibridi ZUGFeRD/Factur-X richiedono ancora una sorgente PDF; usa download XML per conversioni da sorgenti DOCX/TXT. Aggiunta l’opzione include_validation_report_html=true su GET /api/v1/tasks/{task_id} per includere inline il report di validazione HTML sanificato quando disponibile. Gli upload di conversione ora accettano su entrambi gli endpoint i campi opzionali use_seller_master_data e seller_master_data, così i tenant approvati possono attivare dati anagrafici venditore salvati o limitati alla richiesta.

### 2026-06-29
Aggiunto GET /api/v1/tasks/{task_id}/validation-report?download=html|xml per recuperare il report di validazione legato alla prova dell’artefatto risultato rigoroso corrente. Le risposte del report di validazione espongono gli header ID task, SHA-256 dell’artefatto, ID prova di validazione, ID prova del report, tipo di contenuto del report e ID di correlazione.

### 2026-06-10
Invoice data you submit is now the source of truth during hybrid ZUGFeRD generation; the server no longer overrides submitted quantities or totals with values recovered from the uploaded PDF. Deterministic cleanup and tax normalization still apply. Long-running conversions are no longer failed at a fixed 5-minute processing timeout. Tasks now fail only when they stop making progress for the stall window or exceed the absolute 15-minute hard cap, and extraction retries are bounded by a total wall-clock budget.

### 2026-06-09
Clarified that usage-tracking persistence failures are fail-open for response delivery: ready validated artifact responses are not denied, no extra prepaid API credit is consumed, and failed usage events are queued internally for reconciliation.

### 2026-06-02
L’accesso External API è ora documentato come accesso approvato invece di creazione non controllata delle chiavi. Chiarito che nessuno SLA formale, credito di servizio o penale contrattuale si applica salvo accordo in un order form. format è ora obbligatorio su entrambi gli endpoint di conversione; valori mancanti restituiscono 400 FORMAT_REQUIRED e valori non supportati 422 INVALID_FORMAT. download è ora obbligatorio sulle richieste task-result; valori mancanti restituiscono 400 DOWNLOAD_FORMAT_REQUIRED e valori non supportati 400 INVALID_DOWNLOAD_FORMAT. Gli upload di conversione ora accettano client_reference/external_invoice_id e source_system per la riconciliazione lato cliente. Le risposte di conversione accettata e stato task ora includono status_url, primary_result_format, primary_result_url e i campi di riconciliazione inviati.

### 2026-06-01
La conversione strutturata ora accetta tutti i formati di output pubblici: XRECHNUNG, ZUGFeRD, EN16931, UBL e CII. La conversione strutturata ora accetta parti data_file ripetibili e gli alias data_files e data_files[] per export ERP suddivisi. I bundle strutturati multi-file devono descrivere esattamente una fattura e falliscono subito se gli ID fattura del bundle sono mancanti o in conflitto. Chiarito che più documenti fattura devono essere inviati come task di conversione separati, ciascuno con la propria idempotency key.

### 2026-05-27
Aggiunto POST /api/v1/invoices:convert-structured per conversione da dati strutturati con PDF contenitore e CSV/JSON/XML/XLSX/TXT sui formati output supportati. Documentato che i dati strutturati sono l’unica fonte semantica su questo endpoint; il PDF viene usato per l’incorporamento ibrido. Artefatti OpenAPI e Postman aggiornati per la conversione strutturata.

### 2026-05-26
Strict XML and hybrid ZUGFeRD PDF result artifacts now carry internal artifact parity metadata; public clients should use task-status result_artifacts for artifact readiness and validation-state diagnostics. Updated the documented production base URL to https://www.invoice-converter.com/api/v1.

### 2026-05-19
Task-result downloads are now strict retrieval-only: no XML/PDF generation, AI call, repair, or validation runs on GET /api/v1/tasks/{task_id}/result. Strict tasks complete only after a validated artifact is stored; completed tasks without a current proof fail closed with 500 INTERNAL_ARTIFACT_INVARIANT_FAILED. External API conversions are permanently pinned to strict issuance: no draft output, no warning override, and artifact validation always required. Conversions run on a dedicated processing tier chosen by the service. Added additive result_artifacts diagnostics to the task status response, and documented the canonical delivery_channel values PEPPOL, DIRECT_XML, PORTAL, EMAIL_PDF, and UNKNOWN. Documented 422 ZUGFERD_SOURCE_PDF_INCOMPATIBLE, and clarified that missing XRechnung/Peppol target metadata such as BT-10, BT-49, and BG-16 is a validation correction flow rather than a transport retry.

### 2026-05-08
Aggiunti crediti External API prepagati per tenant non Enterprise. Documentato 402 INSUFFICIENT_API_CREDITS per tenant approvati senza fatturazione Enterprise tramite order form o crediti prepagati. Confermato che i replay idempotenti non consumano crediti API aggiuntivi. Chiarito che il routing del modello External API V1 è gestito lato server, mentre profilo e contesto di consegna restano controllati dal chiamante.

### 2026-03-28
Task status responses expose artifact readiness diagnostics for XML/PDF result availability. Documented that strict result downloads only return files after server-side artifact gates pass.

### 2026-03-26
Successful task-result downloads are backed by a server-side validation proof for the returned bytes. The result endpoint returns 503 AUTHORITATIVE_VALIDATION_UNAVAILABLE when required authoritative validation, proof persistence, or hybrid-generation dependencies are unavailable. Cached task-result downloads are reused only when the cached artifact still has a persisted validation proof.

### 2026-03-06
Download task-result resi fedeli al formato per output CII e ZUGFERD. Aggiunto riuso di artefatti risultato in cache per download XML/PDF ripetuti dello stesso task. Quote di polling allineate a bucket rate-limit ponderati e scoped per endpoint.

### 2026-02-23
Aggiunte risposte di errore API più chiare e coerenti su tutti gli endpoint. Opzioni convert ampliate e comportamento download XML/PDF documentato per i risultati task. Sicurezza retry migliorata con requisiti di idempotenza e validazione più rigidi. Artefatti OpenAPI/Postman aggiornati al comportamento API corrente.

## Artefatti di consegna

Scarica gli artefatti di integrazione leggibili da macchina per la Developer API.

- [OpenAPI JSON](/developer-api/v1/openapi.json)
- [Collezione Postman](/developer-api/v1/postman.json)

## Usare Postman e OpenAPI

- Importa la collezione Postman e imposta le variabili di collezione `base_url`, `api_key` e `idempotency_key`.
- Esegui la collezione in ordine: convert, polling stato, poi fetch result.
- Usa OpenAPI JSON per generare client tipizzati, ma copri upload file, polling e gestione del risultato binario con test di integrazione.
- Registra `X-Correlation-ID` nei log così il supporto può tracciare le richieste end-to-end.

## Invia feedback tecnico

Condividi con il nostro team domande di implementazione, rischi e richieste di modifica del contratto.

- [Invia feedback via email](mailto:contact@invoice-converter.com?subject=Feedback%20revisione%20tecnica%20API%20esterna%20V1&body=Ciao%20team%20Invoice-Converter%2C%0D%0A%0D%0AAbbiamo%20revisionato%20la%20documentazione%20API%20esterna%20V1%20e%20abbiamo%20i%20seguenti%20feedback%3A%0D%0A%0D%0A1)%20%0D%0A2)%20%0D%0A3)%20%0D%0A%0D%0ACordiali%20saluti%2C)
