📖
KSeF API 2.0

Guida API KSeF 2.0

Riferimento tecnico completo per l'integrazione con l'API KSeF del Ministero delle Finanze polacco

Testa le mie fatture

Avviso

Questa guida è fornita a scopo informativo e si basa sulla documentazione API KSeF 2.0 e sui nostri test reali nell'ambiente TEST. Le specifiche possono cambiare. Consulta sempre la documentazione ufficiale del Ministero delle Finanze polacco per le informazioni più aggiornate.

1. Ambienti

KSeF fornisce tre ambienti distinti. Utilizza sempre TEST o DEMO per lo sviluppo.

AmbienteURLScopo
TESThttps://api-test.ksef.mf.gov.pl/v2Test liberi, NIP fittizi
DEMOhttps://api-demo.ksef.mf.gov.pl/v2Dimostrazione
PRODhttps://api.ksef.mf.gov.pl/v2Produzione (obbligatorio dal 01/02/2026)

2. Autenticazione

Ogni sessione API richiede l'autenticazione tramite token. Il flusso completo utilizza la crittografia RSA-OAEP del token con la chiave pubblica del KSeF.

Flusso completo (token API)

1. GET  /security/public-key-certificates     → RSA keys
2. POST /auth/challenge                        → challenge + timestampMs
3. RSA-OAEP(token|timestampMs)                 → encrypt with "KsefTokenEncryption" key
4. POST /auth/ksef-token                       → challenge + encryptedToken
   → authenticationToken + referenceNumber (HTTP 202)
5. GET  /auth/{referenceNumber}                → poll until code=200
6. POST /auth/token/redeem                     → exchange → accessToken

Header richiesti per le chiamate autenticate

Authorization: Bearer {accessToken}
Accept: application/json
Content-Type: application/json

Chiavi pubbliche

GET /security/public-key-certificates restituisce 2 certificati:

UsageUtilizzo
KsefTokenEncryptionCrittografia del token durante l'autenticazione
SymmetricKeyEncryptionCrittografia della chiave AES di sessione

Nessun campo fingerprint nella risposta (contrariamente alla documentazione).

3. Sessione Online (interattiva)

Per inviare fatture senza allegati, una alla volta.

1. POST /sessions/online                           → open session
2. POST /sessions/online/{ref}/invoices             → send invoice
3. GET  /sessions/{ref}/invoices/{invoiceRef}        → check status
4. POST /sessions/online/{ref}/close                → close session

Apertura della sessione

{
  "formCode": {"systemCode": "FA (3)", "schemaVersion": "1-0E", "value": "FA"},
  "encryption": {
    "encryptedSymmetricKey": "RSA-OAEP(aes_key, cert_SymmetricKeyEncryption)",
    "initializationVector": "base64(iv_16_bytes)"
  }
}

Il client genera la chiave AES-256 e l'IV, crittografa la chiave con RSA e invia entrambi.

Invio di una fattura

{
  "invoiceHash": "base64(SHA256(xml_raw))",
  "invoiceSize": 2048,
  "encryptedInvoiceHash": "base64(SHA256(xml_encrypted))",
  "encryptedInvoiceSize": 2064,
  "encryptedInvoiceContent": "base64(AES-256-CBC(xml_raw))"
}

Crittografia AES-256-CBC con padding PKCS#7. Stessa chiave/IV della sessione.

4. Sessione Batch (wsadowa)

Per inviare fatture con o senza allegati, in blocco (ZIP).

1. Create ZIP containing XML invoices (faktura_1.xml, faktura_2.xml, ...)
2. Encrypt ZIP with AES-256-CBC + PKCS#7 (NO IV prepend)
3. POST /sessions/batch           → open session, receive upload URL
4. PUT  {uploadUrl}               → upload encrypted ZIP (raw bytes)
5. POST /sessions/batch/{ref}/close  → close and start processing
6. GET  /sessions/{ref}           → poll session status
7. GET  /sessions/{ref}/invoices  → accepted invoices
8. GET  /sessions/{ref}/invoices/failed → rejected invoices

Apertura sessione batch

{
  "formCode": {"systemCode": "FA (3)", "schemaVersion": "1-0E", "value": "FA"},
  "batchFile": {
    "fileSize": 1078,
    "fileHash": "base64(SHA256(zip_raw))",
    "fileParts": [{
      "ordinalNumber": 1,
      "fileSize": 1088,
      "fileHash": "base64(SHA256(zip_encrypted))"
    }]
  },
  "encryption": {
    "encryptedSymmetricKey": "...",
    "initializationVector": "..."
  }
}
CampoValore
batchFile.fileSizeDimensione ZIP prima della crittografia
batchFile.fileHashSHA256 dello ZIP prima della crittografia
fileParts[].fileSizeDimensione ZIP dopo la crittografia
fileParts[].fileHashSHA256 dello ZIP dopo la crittografia

Upload: la risposta contiene partUploadRequests con URL, metodo (PUT) e header (x-ms-blob-type: BlockBlob). Inviare byte crittografati grezzi, senza header Authorization.

Ogni fattura viene elaborata in modo indipendente. Un errore su una fattura NON blocca le altre.

Contrariamente a un'idea diffusa, l'elaborazione batch non è atomica: le fatture valide ricevono il loro ksefNumber anche se altre fatture dello stesso lotto vengono rifiutate.

Risultati per fattura

Dopo la chiusura della sessione batch, ogni fattura viene elaborata in modo indipendente. Consultare i risultati tramite due endpoint separati.

GET /sessions/{ref}/invoices          → accepted invoices (with ksefNumber)
GET /sessions/{ref}/invoices/failed   → rejected invoices (with processingCode + error)

L'elaborazione è parallela: le fatture accettate e rifiutate possono apparire in un ordine diverso rispetto allo ZIP.

5. Codici di elaborazione

Le risposte API utilizzano codici di elaborazione (processingCode) per indicare lo stato della richiesta. Lo stesso codice può avere significati leggermente diversi a seconda dell'endpoint (auth, sessione, fattura, export).

Progressione (100-299)

CodeSignificato
100Processo registrato / accettato per l'elaborazione
150Elaborazione in corso (sostituisce il vecchio codice 300 da RC3)
170Elaborazione completata
200Successo → ksefNumber disponibile, sessione elaborata, export completato
210Export scaduto, non più disponibile per il download

Errori (400-550)

CodeSignificato
400Operazione fallita, richiesta rifiutata
405Errore di verifica del pacchetto (sanity check) / errore di sessione
410Identificatori incoerenti, ambito permessi non valido
415Permessi mancanti, errore decrittazione chiave, allegati non consentiti
420Filtri troppo ampi, limite fatture superato, permesso negato
425Token invalidato / hash file non valido
429Rate limit superato (~100/s, ~300/min, ~1200/h)
430Errore di decompressione, errore verifica fattura, ruolo mancante
435Errore decrittazione file (crittografia errata)
440Sessione annullata (timeout upload), fattura duplicata, operazione vietata
441Errore di verifica del sottoprocesso di elaborazione fattura
445Errore di finalizzazione, nessuna fattura valida trovata
450Token non valido, errore struttura fattura, XML non valido
460Fallimento certificato (non valido, catena non attendibile, revocato)
470Tentativo di utilizzo dei metodi di autorizzazione di una persona deceduta
480Auth bloccata: sospetto incidente di sicurezza (contattare MF tramite modulo)
500Errore server sconosciuto
550Operazione annullata dal sistema (atomica, nessuna elaborazione parziale). Riprovare.

Source : Issue #526, OpenAPI spec, api-changelog.md

6. Limiti

ParametroValore
Dimensione max fattura senza allegati1 MB
Dimensione max fattura con allegati3 MB (configurabile fino a 10 MB)
Max fatture per sessione batch10 000 000
Dimensione max ZIP5 GB
Max parti per ZIP50 (100 MB ciascuna)
Timeout sessione batch non chiusa12h → annullamento automatico (codice 440)

Verificabile tramite GET /limits/context.

7. Allegati (Zalacznik)

Prerequisiti

  • 1.Attivazione : POST /testdata/attachment con {"nip": "..."} (ambiente TEST). In PROD: dichiarazione tramite e-Urząd Skarbowy.
  • 2.Sessione batch obbligatoria : la modalità online rifiuta gli allegati (codice 415).

Verifica

GET /permissions/attachments/status (authenticated)

{"isAttachmentAllowed": true}
// or with revocation date:
{"isAttachmentAllowed": true, "revokedDate": "2026-12-31T23:59:59+00:00"}

Struttura XML

'<Zalacznik>' è un figlio diretto di '<Faktura>' (non di '<Fa>'), con contenuto strutturato:

<Faktura xmlns="http://crd.gov.pl/wzor/2025/06/25/13775/">
  <Naglowek>...</Naglowek>
  <Podmiot1>...</Podmiot1>
  <Podmiot2>...</Podmiot2>
  <Fa>...</Fa>
  <Zalacznik>
    <BlokDanych>
      <MetaDane>
        <ZKlucz>Key</ZKlucz>
        <ZWartosc>Value</ZWartosc>
      </MetaDane>
      <Tabela>
        <Opis>Table description</Opis>
        <TNaglowek>
          <Kol Typ="txt"><NKom>Column 1</NKom></Kol>
          <Kol Typ="int"><NKom>Column 2</NKom></Kol>
        </TNaglowek>
        <Wiersz>
          <WKom>Value 1</WKom>
          <WKom>42</WKom>
        </Wiersz>
      </Tabela>
    </BlokDanych>
  </Zalacznik>
</Faktura>

Tipi di colonna: txt, int, dec, date.

Codici errore allegati

CodeModeMessage
415Online"Wysylanie faktury z zalacznikiem w trybie interaktywnym nie jest dozwolone"
410Batch"Sprzedawca {NIP} nie posiada zgody do wysylania faktur z zalacznikami"

8. Endpoint testdata (ambiente TEST)

Nessuna autenticazione richiesta. Questi endpoint permettono di configurare l'ambiente di test.

EndpointMetodoStatoNotes
/testdata/subjectPOSTOK{"subjectNip": "...", "description": "..."}
/testdata/personPOSTOK{"nip": "...", "pesel": "...", "description": "..."}
/testdata/attachmentPOSTOK{"nip": "..."} — attiva gli allegati
/testdata/attachment/revokePOSTOK{"nip": "..."} — revoca non immediata
/testdata/permissionsPOST500Non funzionante dal lancio di KSeF 2.0

9. Endpoint informativi

Endpoint autenticati per consultare lo stato del proprio account e delle fatture.

EndpointDescription
/permissions/attachments/statusStato autorizzazione allegati
/limits/contextLimiti di sessione (dimensione max, ecc.)
/rate-limitsRate limit attuali
/auth/sessionsSessioni attive
/invoices/query/metadataRicerca fatture (filtro hasAttachment)
/invoices/ksef/{ksefNumber}Scarica fattura per numero KSeF

10. Problemi noti

Punti di attenzione durante l'integrazione con l'API KSeF, basati sui nostri test reali:

ProblemaSourceDettagli
POST /testdata/permissions restituisce 500#296Non funzionante dal lancio di KSeF 2.0. Anche con il formato esatto dello schema OpenAPI, il server restituisce 500 Internal Server Error.
Revoca allegati non immediataTest 04/02/2026Dopo la chiamata a /testdata/attachment/revoke, isAttachmentAllowed rimane true con un revokedDate futuro.
Server TEST lento (codice 150 prolungato)#408, #278Dopo il lancio, l'elaborazione può rimanere nel codice 150 ("Elaborazione in corso") più a lungo del previsto.
Allegato rifiutato in modalità online (415)#674Non è un bug: gli allegati richiedono una sessione batch. La modalità online restituisce 415.

Hai bisogno di aiuto con l'integrazione KSeF?

Ti supportiamo nell'integrazione API: autenticazione, invio fatture, gestione errori e messa in produzione.

Avviso

Questa guida è fornita a scopo informativo e si basa sulla documentazione API KSeF 2.0 e sui nostri test reali nell'ambiente TEST. Le specifiche possono cambiare. Consulta sempre la documentazione ufficiale del Ministero delle Finanze polacco per le informazioni più aggiornate.