ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

KSeF API specifications

The KSeF API is a REST API hosted on ksef.mf.gov.pl, exposing three usage channels — Sesja Interaktywna (interactive), Sesja Wsadowa (batch), and Common (lookup). Authentication by token hierarchy, JSON format with base64-embedded FA(2) XML.

Environments and endpoints

The ministry operates three distinct environments for KSeF:

  • Production (Produkcja). ksef.mf.gov.pl — the legal reference environment. Every invoice that transits there receives a legally valid numer KSeF.
  • Pre-production (Przedprodukcyjna). ksef-test.mf.gov.pl — production mirror environment for vendor integration testing. No legal value. The NIPs used must be real.
  • Demo (Demonstracja). ksef-demo.mf.gov.pl — sandbox with fictitious NIPs and generated data. Ideal for training and early development.
EndpointMethodDescription
/api/online/Session/InitTokenPOSTOpen interactive session with AuthorizationToken
/api/online/Session/InitSignedPOSTOpen XAdES-signed session
/api/online/Session/TerminatePOSTClose current session
/api/online/Invoice/SendPOSTIssue an FA(2) invoice in interactive mode
/api/online/Invoice/Status/{ref}GETSubmission status by reference
/api/online/Invoice/Get/{numKSeF}GETRetrieve invoice by numer KSeF
/api/online/Query/Invoice/SyncPOSTSynchronous invoice search by criteria
/api/online/Query/Invoice/Async/InitPOSTInitialise asynchronous search (volumes)
/api/batch/Session/InitPOSTOpen batch session (Sesja Wsadowa)
/api/batch/Session/ClosePOSTClose and trigger batch processing
/api/common/Status/{ref}GETOngoing batch session status

Authentication — OAuth 2.0 hierarchy

KSeF uses a three-level hierarchy, inspired by OAuth 2.0 but specific to the ministry:

  1. AuthorizationToken. Primary token generated once by the taxpayer, in the KSeF portal (human interface) or via XAdES signature by e-IDAS certificate. Valid 24 months, default scope fakturujący on the owning NIP.
  2. SessionToken. Obtained by InitToken in exchange for the AuthorizationToken. Valid for a 4-hour sliding window. Used to chain invoice operations without paying the auth cost again.
  3. AccessToken (contextual alias). For delegations (e.g. external accountant acting on behalf of the taxpayer). Links the AuthorizationToken to a specific Uprawnienie (right) on a third-party NIP.
bash ksef-init-session.http
POST /api/online/Session/InitToken HTTP/1.1
Host: ksef.mf.gov.pl
Content-Type: application/octet-stream
Content-Encoding: base64

PFNlc3Npb25Ub2tlblJlcXVlc3QgeG1sbnM9Imh0dHA6Ly9rc2VmLm1mLmdvdi5wbC8iPgogIDxJ
ZGVudGlmaWVyVHlwZT5vbmlwPC9JZGVudGlmaWVyVHlwZT4KICA8SWRlbnRpZmllcj41MjYwMjUw
Mjc0PC9JZGVudGlmaWVyPgogIDxBdXRob3JpemF0aW9uVG9rZW4+ZXk...PC9BdXRob3JpemF0
aW9uVG9rZW4+CjwvU2Vzc2lvblRva2VuUmVxdWVzdD4=

HTTP/1.1 201 Created
Content-Type: application/json

{
  "timestamp": "2026-05-19T08:42:11Z",
  "referenceNumber": "20260519-SE-3F4B7A2D9C-DA",
  "sessionToken": {
    "token": "eyJhbGciOiJSUzI1NiIs...",
    "context": {
      "nip": "5260250274",
      "name": "Spółka Sprzedaży Sp. z o.o.",
      "schemaVersion": "1-0E"
    }
  }
}

Interactive flow — Sesja Online

The interactive flow is designed for on-the-fly invoice issuance. This is the preferred mode for ERPs in direct integration and web portals.

  1. POST /api/online/Session/InitToken — open the session, retrieve SessionToken
  2. POST /api/online/Invoice/Send — submit the FA(2) invoice (base64 in invoiceBody)
  3. GET /api/online/Invoice/Status/{ref} — retrieve status and numer KSeF
  4. POST /api/online/Session/Terminate — close the session (frees server resources)
bash ksef-send-invoice.http
POST /api/online/Invoice/Send HTTP/1.1
Host: ksef.mf.gov.pl
SessionToken: eyJhbGciOiJSUzI1NiIs...
Content-Type: application/json

{
  "invoiceHash": {
    "hashSHA": {
      "algorithm": "SHA-256",
      "encoding": "Base64",
      "value": "9c1185a5c5e9fc54612808977ee8f548b2258d31"
    },
    "fileSize": 4892
  },
  "invoicePayload": {
    "type": "plain",
    "invoiceBody": "PD94bWwgdmVyc2lvbj0iMS4wIi..."
  }
}

HTTP/1.1 201 Created
Content-Type: application/json

{
  "elementReferenceNumber": "20260519-SE-3F4B7A2D9C-DA",
  "processingDescription": "Przyjęte",
  "referenceNumber": "20260519-IN-7C8A3D4E5F-AA",
  "timestamp": "2026-05-19T08:42:17Z"
}

The transactional status is in processingDescription. Three main values:

  • Przyjęte — invoice accepted by validator, numer KSeF assigned in referenceNumber
  • Odrzucone — invoice rejected by validator, error code in statusCode
  • W trakcie przetwarzania — asynchronous processing in progress, request to repeat after 1-2 seconds

Batch flow — Sesja Wsadowa

Wsadowa mode allows sending a packet of invoices grouped in a signed ZIP archive, processed asynchronously by KSeF. Preferred mode for ERP vendors handling large volumes.

  1. Local preparation. Build a ZIP archive containing each FA(2) invoice as an individual XML file (one file = one invoice). Limit: 50 invoices per archive, maximum size 100 MB.
  2. Hash and encryption. SHA-256 hash of each included XML file. AES-256-CBC encryption of the archive with a random symmetric key, itself RSA-encrypted with the KSeF public certificate.
  3. POST /api/batch/Session/Init. Submit the manifest (invoice list + hashes + encrypted key). KSeF replies with a deposit URL and a BatchSessionReferenceNumber.
  4. PUT on the deposit URL. Upload the encrypted ZIP archive.
  5. POST /api/batch/Session/Close. Trigger processing.
  6. Polling GET /api/common/Status/{ref}. Track status. Target latency: 5 to 30 minutes depending on volume.

Limits and quotas

LimitValueNote
Sesja Online — requests / NIP / minute60Anti-flood rate limit
Sesja Wsadowa — invoices / batch50Strict XSD limit
Sesja Wsadowa — encrypted ZIP archive size100 MBBeyond: vendor-side segmentation
FA(2) invoice XML size10 MB uncompressedBinary attachments forbidden
Binary attachments0The image PDF is not transmitted in KSeF
SessionToken — duration4-hour sliding windowRenewable during use
AuthorizationToken — duration24 monthsManual renewal via portal
Recommended retry policy3 attempts, exponential backoff 1s/2s/4sOn 5xx or code 21900 (transient timeout)

Error codes 21xxx

KSeF error codes follow a 21xxx convention. Partial catalogue of common errors:

CodeDescriptionAction
21100SessionToken expiredRe-run InitToken
21102SessionToken invalid or revokedCheck AuthorizationToken
21200Issuer NIP does not match tokenCheck token scope and delegation
21300Schemat XSD nieaktualny (outdated schema)Switch to current FA(2) version
21320Schematron violation — rule BR-CO-25 (totals)Recompute P_13_1 + P_14_1 = P_15
21400SHA-256 hash mismatchRecompute the hash post-send
21500Recipient NIP (Podmiot2/NIP) does not exist or inactiveCheck on VAT-R portal
21900Processing in progress, retry after 2sExponential backoff
21999KSeF internal errorRetry; if persistent, support ticket

Common pitfalls

  • Wrong base URL. The test environment (ksef-test) and demo (ksef-demo) are often confused. Verify the NIPs used — real ones for test, fictitious ones for demo. A mistake is rejected with code 21200.
  • Base64 encoding with line breaks. Some base64 libs insert breaks every 76 chars (RFC 2045 MIME). KSeF only accepts base64 without line breaks (strict RFC 4648).
  • Missing Content-Length. On POST with binary body, KSeF requires an exact Content-Length. HTTP libs using Transfer-Encoding: chunked are rejected.
  • Binary attachments. KSeF only accepts pure XML. Any attachment (PDF, image) must be referenced outside KSeF and transmitted via another channel. External cloud storage links are accepted in FaWiersz/DodatkoweInfo.
  • Polish diacritics. ą, ć, ę, ł, ń, ó, ś, ź, ż must be UTF-8 encoded (never Windows-1250 or ISO 8859-2). KSeF rejects misencoded characters with code 21420.