📖
KSeF API 2.0

Przewodnik API KSeF 2.0

Kompletna dokumentacja techniczna integracji z API KSeF Ministerstwa Finansów

Przetestuj moje faktury

Zastrzeżenie

Ten przewodnik jest udostępniany w celach informacyjnych i opiera się na dokumentacji API KSeF 2.0 oraz naszych rzeczywistych testach w środowisku TEST. Specyfikacje mogą ulec zmianie. Zawsze sprawdzaj oficjalną dokumentację Ministerstwa Finansów w celu uzyskania najnowszych informacji.

1. Środowiska

KSeF udostępnia trzy odrębne środowiska. Do prac programistycznych zawsze używaj TEST lub DEMO.

ŚrodowiskoURLPrzeznaczenie
TESThttps://api-test.ksef.mf.gov.pl/v2Swobodne testy, fikcyjne NIP-y
DEMOhttps://api-demo.ksef.mf.gov.pl/v2Demonstracja
PRODhttps://api.ksef.mf.gov.pl/v2Produkcja (obowiązkowa od 01.02.2026)

2. Uwierzytelnianie

Każda sesja API wymaga uwierzytelnienia tokenem. Pełny przepływ wykorzystuje szyfrowanie RSA-OAEP tokenu kluczem publicznym KSeF.

Pełny przepływ (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

Wymagane nagłówki dla uwierzytelnionych wywołań

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

Klucze publiczne

GET /security/public-key-certificates zwraca 2 certyfikaty:

UsageZastosowanie
KsefTokenEncryptionSzyfrowanie tokenu podczas uwierzytelniania
SymmetricKeyEncryptionSzyfrowanie klucza AES sesji

Brak pola fingerprint w odpowiedzi (w przeciwieństwie do dokumentacji).

3. Sesja Online (interaktywna)

Do wysyłania faktur bez załączników, pojedynczo.

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

Otwarcie sesji

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

Klient generuje klucz AES-256 i IV, szyfruje klucz RSA, wysyła oba.

Wysyłanie faktury

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

Szyfrowanie AES-256-CBC z paddingiem PKCS#7. Ten sam klucz/IV co sesja.

4. Sesja Batch (wsadowa)

Do wysyłania faktur z załącznikami lub bez, w paczce (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

Otwarcie sesji 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": "..."
  }
}
PoleWartość
batchFile.fileSizeRozmiar ZIP przed szyfrowaniem
batchFile.fileHashSHA256 ZIP przed szyfrowaniem
fileParts[].fileSizeRozmiar ZIP po szyfrowaniu
fileParts[].fileHashSHA256 ZIP po szyfrowaniu

Upload: odpowiedź zawiera partUploadRequests z URL, metodą (PUT) i nagłówkami (x-ms-blob-type: BlockBlob). Wysyłaj surowe zaszyfrowane bajty, bez nagłówka Authorization.

Każda faktura jest przetwarzana niezależnie. Błąd jednej faktury NIE blokuje pozostałych.

Wbrew powszechnemu przekonaniu, przetwarzanie batch nie jest atomowe: poprawne faktury otrzymują swój ksefNumber, nawet jeśli inne faktury z tej samej paczki zostały odrzucone.

Wyniki per faktura

Po zamknięciu sesji batch każda faktura jest przetwarzana niezależnie. Sprawdź wyniki za pomocą dwóch oddzielnych endpointów.

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

Przetwarzanie jest równoległe: zaakceptowane i odrzucone faktury mogą pojawić się w innej kolejności niż w ZIP.

5. Kody przetwarzania

Odpowiedzi API używają kodów przetwarzania (processingCode) do wskazania statusu żądania. Ten sam kod może mieć nieco inne znaczenie w zależności od endpointu (auth, sesja, faktura, eksport).

Postęp (100-299)

CodeZnaczenie
100Proces zarejestrowany / przyjęty do przetwarzania
150W trakcie przetwarzania (zastępuje dawny kod 300 od RC3)
170Przetwarzanie zakończone
200Sukces → ksefNumber dostępny, sesja przetworzona, eksport zakończony
210Eksport wygasł, niedostępny do pobrania

Błędy (400-550)

CodeZnaczenie
400Operacja nieudana, żądanie odrzucone
405Błąd weryfikacji paczki (sanity check) / błąd sesji
410Niespójne identyfikatory, nieprawidłowy zakres uprawnień
415Brakujące uprawnienia, błąd deszyfrowania klucza, załączniki niedozwolone
420Filtry zbyt szerokie, przekroczono limit faktur, brak uprawnień
425Token unieważniony / nieprawidłowy hash pliku
429Przekroczono rate limit (~100/s, ~300/min, ~1200/h)
430Błąd dekompresji, błąd weryfikacji faktury, brakująca rola
435Błąd deszyfrowania pliku (nieprawidłowe szyfrowanie)
440Sesja anulowana (timeout uploadu), duplikat faktury, zabroniona operacja
441Błąd weryfikacji podprocesu przetwarzania faktury
445Błąd finalizacji, nie znaleziono prawidłowej faktury
450Nieprawidłowy token, błąd struktury faktury, nieprawidłowy XML
460Niepowodzenie certyfikatu (nieprawidłowy, niezaufany łańcuch, unieważniony)
470Próba użycia metod autoryzacji osoby zmarłej
480Autoryzacja zablokowana: podejrzenie incydentu bezpieczeństwa (skontaktuj się z MF przez formularz)
500Nieznany błąd serwera
550Operacja anulowana przez system (atomowa, brak częściowego przetwarzania). Spróbuj ponownie.

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

6. Limity

ParametrWartość
Maks. rozmiar faktury bez załączników1 MB
Maks. rozmiar faktury z załącznikami3 MB (konfigurowalne do 10 MB)
Maks. faktur na sesję batch10 000 000
Maks. rozmiar ZIP5 GB
Maks. części na ZIP50 (po 100 MB każda)
Timeout niezamkniętej sesji batch12h → automatyczne anulowanie (kod 440)

Weryfikowalne przez GET /limits/context.

7. Załączniki (Zalacznik)

Wymagania wstępne

  • 1.Aktywacja : POST /testdata/attachment z {"nip": "..."} (środowisko TEST). W PROD: deklaracja przez e-Urząd Skarbowy.
  • 2.Wymagana sesja batch : tryb online odrzuca załączniki (kod 415).

Weryfikacja

GET /permissions/attachments/status (authenticated)

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

Struktura XML

'<Zalacznik>' jest bezpośrednim dzieckiem '<Faktura>' (nie '<Fa>'), ze strukturą ustrukturyzowaną:

<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>

Typy kolumn: txt, int, dec, date.

Kody błędów załączników

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

8. Endpointy testdata (środowisko TEST)

Nie wymaga uwierzytelnienia. Te endpointy pozwalają skonfigurować środowisko testowe.

EndpointMetodaStatusNotes
/testdata/subjectPOSTOK{"subjectNip": "...", "description": "..."}
/testdata/personPOSTOK{"nip": "...", "pesel": "...", "description": "..."}
/testdata/attachmentPOSTOK{"nip": "..."} — aktywuje załączniki
/testdata/attachment/revokePOSTOK{"nip": "..."} — rewokacja nie jest natychmiastowa
/testdata/permissionsPOST500Uszkodzone od uruchomienia KSeF 2.0

9. Endpointy informacyjne

Uwierzytelnione endpointy do sprawdzania statusu konta i faktur.

EndpointDescription
/permissions/attachments/statusStatus autoryzacji załączników
/limits/contextLimity sesji (maks. rozmiar itp.)
/rate-limitsAktualne rate limity
/auth/sessionsAktywne sesje
/invoices/query/metadataWyszukiwanie faktur (filtr hasAttachment)
/invoices/ksef/{ksefNumber}Pobierz fakturę po numerze KSeF

10. Znane problemy

Kwestie do uwzględnienia podczas integracji z API KSeF, na podstawie naszych rzeczywistych testów:

ProblemSourceSzczegóły
POST /testdata/permissions zwraca 500#296Uszkodzone od uruchomienia KSeF 2.0. Nawet z dokładnym formatem schematu OpenAPI, serwer zwraca 500 Internal Server Error.
Rewokacja załączników nie jest natychmiastowaTesty 04.02.2026Po wywołaniu /testdata/attachment/revoke, isAttachmentAllowed pozostaje true z przyszłą datą revokedDate.
Serwer TEST wolny (przedłużony kod 150)#408, #278Po uruchomieniu przetwarzanie może pozostawać w kodzie 150 ("W trakcie przetwarzania") dłużej niż oczekiwano.
Załącznik odrzucony w trybie online (415)#674To nie jest błąd: załączniki wymagają sesji batch. Tryb online zwraca 415.

Potrzebujesz pomocy z integracją KSeF?

Wspieramy w integracji API: uwierzytelnianie, wysyłka faktur, obsługa błędów i wdrożenie produkcyjne.

Zastrzeżenie

Ten przewodnik jest udostępniany w celach informacyjnych i opiera się na dokumentacji API KSeF 2.0 oraz naszych rzeczywistych testach w środowisku TEST. Specyfikacje mogą ulec zmianie. Zawsze sprawdzaj oficjalną dokumentację Ministerstwa Finansów w celu uzyskania najnowszych informacji.