KSeF (Krajowy System e-Faktur, “National e-Invoice System”) is the mandatory platform of the Polish Ministry of Finance for B2B electronic invoicing. Polish VAT-registered companies must submit every invoice in FA(3) format to KSeF and receive an official identifier (Numer KSeF) before distributing it to the customer.
B2Brouter handles the full cycle: signing with the tax certificate, transforming to FA(3), submitting, receiving the KSeF number, and generating the QR code and the official receipt (UPO).
Who is it for — Companies with a Polish NIP (Numer Identyfikacji Podatkowej). Non-Polish companies cannot activate KSeF nor select it as the transport on a Polish contact — the invoice would not be sent.
KSeF environments — The Ministry publishes three: Production, Demo (real data without fiscal effects) and Test (open sandbox for integrations). B2Brouter’s production instance talks to KSeF Production; the staging instance talks to KSeF Test or Demo depending on the certificate configuration.
Production — Access the official KSeF web portal of the Polish Ministry of Finance at ap.ksef.mf.gov.pl/web identifying yourself with your fiscal identity system (Profil Zaufany, qualified signature, or similar). Inside the portal, in the certificates/credentials section, generate an authentication certificate linked to your NIP and export it in PKCS#12 (.p12 or .pfx) format with a password. The file you get has a name similar to <NIP>_Uwierzytelnianie.pfx (Uwierzytelnianie = Authentication).
Test (testing and integrations) — The equivalent test web portal is ap-test.ksef.mf.gov.pl/web. You can generate a self-signed certificate with OpenSSL; the subject must include the NIP in the field serialNumber=TINPL-<NIP>. Before using it, register it manually on that same portal: without this step, KSeF Test will reject every signature from that certificate as unknown.
Only PKCS#12 (.p12 / .pfx) works — A .crt file is not valid: it only contains the public part, not the private key, and KSeF needs both to authenticate the signature. If the portal gives you something else, re-export it explicitly choosing PKCS#12 and ticking “include the private key”. Only as a last resort, if you have the .crt and the .key separately, you can combine them with OpenSSL:
openssl pkcs12 -export \
-in ksef_certificate.crt \
-inkey ksef_private_key.key \
-out ksef_certificate.p12 \
-name "<COMPANY_NAME> <NIP>" \
-passout pass:<PASSWORD>
Encryption algorithm — 3DES or AES — If you get the error “Certificate password is invalid” even though the password is correct, the file is encrypted with an old algorithm (RC2-40bit, typical of exports done from old Windows). KSeF and B2Brouter only accept 3DES or AES. Re-export with OpenSSL:
Environment — Production by default. Demo or Test only if you are testing.
Save.
When you save, B2Brouter connects to KSeF, validates the certificate and checks that the NIP of the subject matches the account NIP (or that the company is authorised via ZAW-FA). If the validation succeeds, the certificate is stored and KSeF is active for your account.
Once KSeF is active, the tax report is generated on its own — You don’t need to do anything else. Every invoice issued to a Polish contact via KSeF will automatically generate its tax report and will be submitted to KSeF as part of the same issuing flow. If you integrate via API, configure the tax_report_setting with auto_generate: true and auto_send: true so the flow is equivalent to the UI one.
If the certificate subject does not match the account NIP — You must submit the ZAW-FA form on the official portal to authorise your company to issue invoices with that certificate. Until ZAW-FA is approved, KSeF will reject invoices with error 450 or similar.
Before issuing an invoice to a customer, the customer must exist in contacts.
Contacts → New contact.
Select the customer’s country.
Enter the tax identifier — it depends on the customer’s country (see table below).
Validate identifier and continue — for Polish customers, B2Brouter connects to the Ministry registry to verify the NIP and autocomplete the legal name.
Fill in the address (street, postal code, city).
Configure the delivery method and choose KSeF as transport. If KSeF does not appear, switch the network type to the one that shows KSeF in the list (in some accounts it is an open network that bundles several transports).
Save.
Three identification structures depending on the customer’s country
KSeF requires informing the customer using one of three mutually exclusive structures. If you mix formats (NIP with prefix, prefix without country, etc.) in the same account, you will get intermittent errors — some invoices pass and others are rejected.
Customer type
Identifier to enter
How KSeF renders it in XML
Polish
NIP (exactly 10 digits, without the PL prefix)
Podmiot2/DaneIdentyfikacyjne/NIP
Other EU country
VAT number without country prefix (e.g. 123456789 for DE123456789)
Do not mix formats — For the same customer, always send the same type of identifier. If you send them as Polish on one invoice (PL + NIP) and as EU on the next (DE + VAT), KSeF will apply different validation rules and the result will be inconsistent.
Greece: fiscal code EL, not GR — On the EU fiscal field (in KSeF, KodUE), Greece is identified with EL. For the address, GR is used. If the form lets you pick GR in the fiscal field, change it to EL; otherwise KSeF will reject the invoice with the error KodUE: 'GR' is not an element of the set {...}.
Currency — PLN for domestic invoices. For foreign currencies, fill in the exchange rate to PLN on the invoice date: it will be sent to KSeF’s KursWalutyZ field.
Notes — free text that will appear as the invoice footer (Stopka) in the official PDF. Useful for legal clauses, contractual conditions, or any information that does not fit in another field.
Cross-border services not subject to tax (Art. 28b)
Exempt lines (zw) — legal basis in the Comment — For lines with exempt VAT, state the legal basis (e.g. “art. 43 ust. 1 pkt 37 ustawy VAT”) in the line’s Comment field. The PDF will show two paragraphs: a generic legal annotation (automatic) and the comment you wrote.
Exchange rate: the rate of the day prior to the VAT date, per the ECB or NBP tables.
Do not use zw (exempt) for exports — An export is 0 EX (export zero-rate, P_13_6_3). If you use zw, the amount is duplicated between the domestic zero-rate and exempt boxes, and KSeF rejects or distorts the declaration.
On the invoice detail page you will see the current status, the Numer KSeF once registered, and the UPO receipt.
Sending → Registered → (QR + Numer KSeF + UPO)
↘ Error
Sending — B2Brouter has signed and submitted the document. Effective registration by KSeF can take a few minutes, especially at peak hours or month-end.
Registered ✅ — KSeF has validated and assigned the Numer KSeF (NrKSeF). The QR code on the printed invoice now shows this number, and the official registration receipt becomes available (see below).
Error ❌ — KSeF has rejected the document. The reason appears on the invoice page (code + description in Polish).
The QR appears right away, but that does not mean KSeF has accepted the invoice — B2Brouter generates the QR code locally from the cryptographic hash, the NIP and the date: it is visible immediately, even if the invoice will end up in error. The only reliable indicator of acceptance is the Registered status. If the status is Error, the invoice is not registered in KSeF, regardless of the QR or link generated. While the invoice is Sending, the QR carries the OFFLINE label.
What it is. The UPO (Urzędowe Poświadczenie Odbioru, “Official Confirmation of Receipt”) is the receipt that KSeF issues when it accepts and registers the invoice. It works as an administrative acknowledgement: it is the legal proof, with fiscal value, that you have fulfilled the obligation of registering the invoice in KSeF at a specific moment.
Technically, it is an XML document digitally signed by the Polish Ministry of Finance. It contains the Numer KSeF (NrKSeF) assigned to the invoice, the exact timestamp of registration, and the Ministry signature. It is not a visual PDF — it is a machine-readable legal proof.
Where it comes from. KSeF generates it the moment it validates and accepts the invoice. It is not generated by B2Brouter or by you.
How to confirm the registration from B2Brouter. When the invoice moves to Registered, open the associated KSeF tax report (linked from the invoice page). On the Activity tab, you will see the successful submission event with the assigned Numer KSeF — confirmation that KSeF has received, validated and registered the document.
How to obtain the UPO XML file for your accounting archive. The original file is available through two channels:
From the official KSeF portal — ap.ksef.mf.gov.pl/web (or ap-test.ksef.mf.gov.pl/web for the test environment). By logging in with your fiscal identity system, you can browse and download the UPOs of your account directly from the Ministry — they are the official original.
Via the B2Brouter API — if you integrate with the API, the UPO is available as an attachment of the tax report. See the KSeF Developer Guide.
Keep the UPOs with the invoice — They have legal value before a tax inspection. Download them from KSeF or via API and archive them together with the original invoice.
Open the invoice and read the error code and description.
Correct the problematic data (contact, NIP, amounts…).
Resend the invoice. B2Brouter retries the registration with KSeF using the corrected data.
Exception — invoice number already seen by KSeF — If the rejection comes from the fact that the invoice number has already been used in a previous submission, you cannot resubmit the same document: delete it, correct the data, and create a new invoice with a different number.
A corrective invoice (faktura korygująca) modifies a previous KSeF invoice. The document links the original (DaneFaKorygowanej) and restates the affected lines with an indication of the previous and new state.
Open the original invoice already registered in KSeF.
Create corrective invoice — B2Brouter automatically fills in the KSeF number, the invoice number, and the date of the original.
Indicate the Effect type (TypKorekty):
1 — Effect on the date of the original invoice. Use: corrections of errors that existed when issued (wrong amount, wrong VAT rate).
2 — Effect on the date of the corrective invoice. Use: subsequent events (returns, post-sale discounts).
3 — Effect on a different date — state it explicitly.
Update the lines to the new state (quantities, prices, VAT rates).
If you want to add a textual correction reason (e.g. “Korekta ilości — dostawa niepełna”) or any associated legal text, write it in the invoice’s Notes field: it is sent to the document’s official footer (Stopka/Informacje/StopkaFaktury) and is visible on the KSeF PDF.
Issue and send.
“Before / after” state — The corrective invoice you issue from the form carries the lines with the new values directly; this is the typical case and is enough for most corrections. If you need the formal before/after representation (original cancelled lines plus new lines on the same document, with a Stan przed marker per line), this option is only available via API: see the Developer Guide.
Once KSeF is active on the account, your NIP is registered as a recipient and Polish suppliers can send invoices directly to you.
Expenses → you will find all received KSeF invoices here.
Open an invoice to see its detail.
Where to find the Numer KSeF of a received invoice — The official KSeF number (NrKSeF) does not appear on the PDF preview, but in the Activity section of the received invoice (format XXXXXXXXXX-YYYYMMDD-XXXXXXXXXXXX-XX). The QR code is only visible on the PDF if the supplier included it on their image.
An invoice the supplier claims to have sent but does not appear in Expenses — First verify that the PDF sent by the supplier carries a KSeF QR code. Without a QR, the invoice was not sent via KSeF — the supplier may not have completed the registration. If there is a QR, scan it and copy its URL: with that URL we can check whether the document actually exists in KSeF.
Approved / Refused — the status you have assigned (no message is sent to the supplier; KSeF does not have an acceptance/rejection channel equivalent to Peppol’s).
Certificate rejected despite the correct password — the PKCS#12 is encrypted with an old algorithm (RC2-40bit), typical of exports from old Windows. Re-export with 3DES or AES (see § 1).
450 - Nip nabywcy: '…' jest nieprawidłowy — customer NIP invalid. Check 10 digits + check digit. For EU contacts, use the EU VAT number without prefix (see § 2).
KodUE: 'GR' is not an element of the set — Greece on the EU fiscal field must be EL, not GR. Edit the contact and fix it.
“Contact Email can’t be blank” — the contact’s transport is email but there is no address. Add an email or change the transport.
Status Error but QR and URL were generated — normal. The QR is computed locally and does not depend on KSeF’s acceptance. The Error status is authoritative: the invoice is not registered.
An invoice the supplier claims to have sent but does not appear in Expenses — check that the supplier’s PDF carries a KSeF QR code. Without QR, it was not actually registered.
VAT summary shows “23% lub 22%” — official Ministry template label, combining the historical (22 %) and current (23 %) rates in a single field. It is not an error.
“Nazwa banku” (bank name) field empty — KSeF does not require the bank name and B2Brouter does not auto-populate it. If you need it, add it to the Notes field.
This manual describes the UI. If you integrate with B2Brouter via API, the official reference is the KSeF Developer Guide — it covers the Tax Report Settings, Tax Reports, Invoices and Contacts endpoints, the full JSON-to-FA(3) mapping, the status tracking webhooks, and the UPO download.
Authentication via static API key (header X-B2B-API-Key) + API version (X-B2B-API-Version). KSeF-specific functionalities require version 2025-10-13 or later.