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.
| Endpoint | Method | Description |
|---|---|---|
/api/online/Session/InitToken | POST | Open interactive session with AuthorizationToken |
/api/online/Session/InitSigned | POST | Open XAdES-signed session |
/api/online/Session/Terminate | POST | Close current session |
/api/online/Invoice/Send | POST | Issue an FA(2) invoice in interactive mode |
/api/online/Invoice/Status/{ref} | GET | Submission status by reference |
/api/online/Invoice/Get/{numKSeF} | GET | Retrieve invoice by numer KSeF |
/api/online/Query/Invoice/Sync | POST | Synchronous invoice search by criteria |
/api/online/Query/Invoice/Async/Init | POST | Initialise asynchronous search (volumes) |
/api/batch/Session/Init | POST | Open batch session (Sesja Wsadowa) |
/api/batch/Session/Close | POST | Close and trigger batch processing |
/api/common/Status/{ref} | GET | Ongoing batch session status |
Authentication — OAuth 2.0 hierarchy
KSeF uses a three-level hierarchy, inspired by OAuth 2.0 but specific to the ministry:
- 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.
- SessionToken. Obtained by
InitTokenin exchange for the AuthorizationToken. Valid for a 4-hour sliding window. Used to chain invoice operations without paying the auth cost again. - 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.
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.
POST /api/online/Session/InitToken— open the session, retrieveSessionTokenPOST /api/online/Invoice/Send— submit the FA(2) invoice (base64 ininvoiceBody)GET /api/online/Invoice/Status/{ref}— retrieve status andnumer KSeFPOST /api/online/Session/Terminate— close the session (frees server resources)
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 inreferenceNumberOdrzucone— invoice rejected by validator, error code instatusCodeW 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.
- 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.
- 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.
- POST /api/batch/Session/Init. Submit the manifest
(invoice list + hashes + encrypted key). KSeF replies with a deposit URL
and a
BatchSessionReferenceNumber. - PUT on the deposit URL. Upload the encrypted ZIP archive.
- POST /api/batch/Session/Close. Trigger processing.
- Polling GET /api/common/Status/{ref}. Track status. Target latency: 5 to 30 minutes depending on volume.
Limits and quotas
| Limit | Value | Note |
|---|---|---|
| Sesja Online — requests / NIP / minute | 60 | Anti-flood rate limit |
| Sesja Wsadowa — invoices / batch | 50 | Strict XSD limit |
| Sesja Wsadowa — encrypted ZIP archive size | 100 MB | Beyond: vendor-side segmentation |
| FA(2) invoice XML size | 10 MB uncompressed | Binary attachments forbidden |
| Binary attachments | 0 | The image PDF is not transmitted in KSeF |
| SessionToken — duration | 4-hour sliding window | Renewable during use |
| AuthorizationToken — duration | 24 months | Manual renewal via portal |
| Recommended retry policy | 3 attempts, exponential backoff 1s/2s/4s | On 5xx or code 21900 (transient timeout) |
Error codes 21xxx
KSeF error codes follow a 21xxx convention. Partial catalogue of common errors:
| Code | Description | Action |
|---|---|---|
| 21100 | SessionToken expired | Re-run InitToken |
| 21102 | SessionToken invalid or revoked | Check AuthorizationToken |
| 21200 | Issuer NIP does not match token | Check token scope and delegation |
| 21300 | Schemat XSD nieaktualny (outdated schema) | Switch to current FA(2) version |
| 21320 | Schematron violation — rule BR-CO-25 (totals) | Recompute P_13_1 + P_14_1 = P_15 |
| 21400 | SHA-256 hash mismatch | Recompute the hash post-send |
| 21500 | Recipient NIP (Podmiot2/NIP) does not exist or inactive | Check on VAT-R portal |
| 21900 | Processing in progress, retry after 2s | Exponential backoff |
| 21999 | KSeF internal error | Retry; 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 usingTransfer-Encoding: chunkedare 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.