KSeF
The KSeF (Krajowy System e-Faktur - National e-Invoice System) is Poland’s mandatory electronic invoicing system operated by the Polish Ministry of Finance. KSeF ensures the integrity and authenticity of invoices through structured XML format submission and digital certification.
These regulations require businesses operating in Poland to adopt systems capable of securely generating, validating, and transmitting invoices to the KSeF platform. B2Brouter’s REST API provides a technical solution that allows your business to be compliant with KSeF, offloading the complexities to B2Brouter and allowing you to focus on your business logic.
What is KSeF?
Section titled “What is KSeF?”KSeF is Poland’s centralized e-invoicing platform that became mandatory for VAT taxpayers. It ensures that all invoices are:
- Validated against official XML schemas (FA structure)
- Digitally certified using qualified certificates
- Securely stored by the Polish tax authority
- Verifiable through an official receipt (UPO - Urzędowe Poświadczenie Odbioru)
In practice, KSeF requires:
- Creating a structured invoice XML file conforming to FA schema variant 3 - FA(3)
- Authenticating with the KSeF platform using a qualified electronic certificate linked to your Polish NIP
- Submitting the invoice to KSeF for validation and registration
- Receiving and storing the UPO (Official Receipt) as proof of registration
- Including the QR code with the KSeF reference number on issued invoices
With B2Brouter you can abstract much of the complexities of this process and comply with KSeF. You will need to provide your qualified electronic certificate (PKCS#12 format), and B2Brouter will handle authentication, submission, and UPO retrieval.
B2Brouter generates tax reports using the FA(3) format (Form variant 3, schema version 1-0E), which is the current standard for KSeF submissions.
Setting up KSeF with B2Brouter API
Section titled “Setting up KSeF with B2Brouter API”The first step is to configure KSeF for each account (identified by Polish NIP) for which you want to submit tax reports. You can refer to the Tax Report Settings Guide for a full description of the process.
B2Brouter Environments and KSeF Integration
Section titled “B2Brouter Environments and KSeF Integration”Start with sandbox for initial API testing and payload validation — KSeF submissions are simulated in sandbox, so no KSeF certificate is required. Switch to the staging environment when you are ready to test with a real KSeF certificate against the KSeF test or demo environment.
B2Brouter connects to different KSeF environments based on your configuration:
| B2Brouter Environment | Available KSeF Environments | Certificate Requirements |
|---|---|---|
Production APIapi.b2brouter.net | KSeF Production only | Production KSeF certificate |
Staging APIapi-staging.b2brouter.net | KSeF Test (default) KSeF Demo (configurable) | Test: Test KSeF certificate or self-signed Demo: Pre-production KSeF certificate |
For development and testing:
- Use the Staging API (
api-staging.b2brouter.net) - By default, it connects to KSeF’s test environment
- Accepts test KSeF certificates (recommended)
- Also accepts self-signed certificates for quick development and integration testing
- You can optionally configure the demo environment by setting
environment: "demo"when creating the tax report setting- Requires a pre-production KSeF certificate
- For production, only production KSeF certificates will work
Certificate Requirements
Section titled “Certificate Requirements”The authentication towards KSeF uses digital certificates in PKCS#12 format (.p12 or .pfx). The type of certificate required depends on the KSeF environment:
For Production Environment:
- Production KSeF certificate
- Client must log in using their qualified signature or trusted profile (Profil Zaufany)
- Access the KSeF section and generate a dedicated KSeF certificate linked to their NIP
- Certificate subject must match your Polish NIP or be authorized via ZAW-FA
- Password/PIN for the certificate
For Demo Environment (Pre-production):
- Pre-production KSeF certificate
- Certificate must be in PKCS#12 format (.p12 or .pfx)
- Certificate subject must match your Polish NIP or be authorized via ZAW-FA
- Password/PIN for the certificate
For Test Environment (Development):
- Test KSeF certificate (recommended) or self-signed certificate (for development only)
- Certificate must be in PKCS#12 format (.p12 or .pfx)
- For self-signed certificates: certificate serial number should match the VAT number (NIP)
- Password/PIN for the certificate
Example: Encoding your certificate
# Encode your certificate to base64 without line breaksbase64 -w 0 your-certificate.p12 > certificate-base64.txtCreating KSeF Tax Report Setting
Section titled “Creating KSeF Tax Report Setting”You need to configure the KSeF integration for each company you want to submit structured invoices for. This configuration defines how B2Brouter handles invoice generation and submission to KSeF on behalf of your system. You must configure these settings per company before submitting any invoice.
- This configuration step will onboard the client to KSeF and perform a connection test.
- If the certificate or configuration is invalid, the endpoint will return an error.
Example request:
curl --request GET \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_report_settings \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report_setting": { "code": "ksef", "type_operation": "services", "credit_note_code": "1", "certificate": "MIIKZAIBAzCCCh4GCSqGSIb3DQEHAaCCCg8Egg...", "certificate_pin": "YourCertificatePassword", "auto_generate": true, "auto_send": true, "enabled": true } }'Parameters:
code: Must be “ksef”type_operation: Default operation type (“services” or “goods”)credit_note_code: Default correction effect code (“1”, “2”, or “3”)certificate: Your PKCS#12 certificate encoded in base64certificate_pin: Password for the certificateauto_generate: Automatically generate tax reports for invoicesauto_send: Automatically send tax reports to KSeF
Working with KSeF Tax Reports
Section titled “Working with KSeF Tax Reports”B2Brouter provides two ways to work with KSeF:
- Tax Report API: For direct control over tax report creation and submission (RECOMMENDED).
- Invoice API: If you use B2Brouter for issuing invoices, tax reports are automatically generated.
Tax Report API
Section titled “Tax Report API”The Tax Report API gives you maximum control over the KSeF submission process. You can create tax reports by providing structured JSON data that B2Brouter will convert to FA(3) XML format.
The structure of the JSON format for B2Brouter tax reports is based on PEPPOL Continuous Transaction Control (CTC). This means that B2Brouter Tax Report API is a universal API not only geared towards KSeF but designed to handle tax reporting around the world.
Important: Tax reports for KSeF use tax_report_lines and tax_breakdowns. Each tax_report_line represents an invoice line item with its own quantity, position, unit_code, price, and tax information.
Create a Tax Report
Section titled “Create a Tax Report”To create a KSeF tax report, call the create tax report endpoint.
Example: Basic VAT Invoice
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "invoice_number": "F/2025/11/001", "description": "Consulting services", "customer_party_name": "Example Company Sp. z o.o.", "customer_party_tax_id": "1234567890", "customer_party_address": "Address 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 1230.00, "tax_amount": 230.00, "type_operation": "services", "tax_report_lines": [ { "position": 1, "quantity": 10, "unit_code": "EA", "description": "Consulting hours", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 1000.0, "tax_amount": 230.00 } ] } }'Example: Corrective Invoice (KOR)
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "KOR", "amend_type": "2", "invoice_date": "2025-11-08", "tax_point_date": "2025-11-07", "invoice_number": "FK/2025/11/001", "description": "Correction of invoice F/2025/11/001", "amended_ksef_number": "1234567890-20251107-ABCD1234-EF", "amended_date": "2025-11-07", "amended_number": "F/2025/11/001", "customer_party_name": "Example Company Sp. z o.o.", "customer_party_tax_scheme": "9945", "customer_party_tax_id": "1234567890", "customer_party_address": "Address 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 1230.00, "tax_amount": 230.00, "type_operation": "services", "tax_report_lines": [ { "position": 1, "quantity": 10, "unit_code": "EA", "description": "Consulting hours", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00, "ksef_amended": true }, { "position": 1, "quantity": 10, "unit_code": "PCE", "description": "Consulting hours - new line", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 1000.0, "tax_amount": 230.00 } ] } }'Example: Exempt Export of Goods - VAT Invoice (foreign currency)
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "invoice_number": "F/2025/11/003", "description": "Sample Exempt VAT Invoice - Export of Goods", "customer_party_name": "EFG Ltd.", "customer_party_tax_id": "1234567890", "customer_party_address": "Flower (St) 1, Seattle, WA 99999", "customer_party_country": "us", "currency": "USD", "exchange_rate": 3.65, "tax_inclusive_amount": 8000, "tax_amount": 0, "type_operation": "goods", "tax_report_lines": [ { "position": 1, "quantity": 20, "unit_code": "szt.", "description": "lodówka Zimnotech mk1", "price": 400, "tax_code": "0 EX", "tax_exclusive_amount": 8000, "tax_amount": 0, "tax_inclusive_amount": 8000 } ], "tax_breakdowns": [ { "name": "PTU", "category": "E", "percent": 0.0, "taxable_base": 8000, "tax_amount": 0, "comment": "reason why exempt" } ] } }'Example: VAT Invoice (full payment received at time of issue) - Zaplacono
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "payment_date": "2025-11-07", "payable_amount": 0, "invoice_number": "F/2025/11/004", "description": "Sample VAT Invoice (full payment has been received at the time of issue)", "customer_party_name": "Example Company Sp. z o.o.", "customer_party_tax_scheme": "9945", "customer_party_tax_id": "1234567890", "customer_party_address": "Address 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 1230.00, "tax_amount": 230.00, "type_operation": "goods", "tax_report_lines": [ { "position": 1, "quantity": 10, "unit_code": "EA", "description": "product 1", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 1000.0, "tax_amount": 230.00 } ] } }'Example: ZAL Invoice (advance payment)
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "ZAL", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "payment_date": "2025-11-07", "payable_amount": 0, "invoice_number": "F/2025/11/005", "description": "Sample ZAL Invoice (full payment has been received at the time of issue)", "customer_party_name": "Example Company Sp. z o.o.", "customer_party_tax_scheme": "9945", "customer_party_tax_id": "1234567890", "customer_party_address": "Address 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 1230.00, "tax_amount": 230.00, "type_operation": "goods", "tax_report_lines": [ { "position": 1, "quantity": 10, "unit_code": "EA", "description": "product 1", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 1000.0, "tax_amount": 230.00 } ] } }'Example: ROZ Invoice (settlement of advance payments)
A ROZ invoice settles the remaining amount after all advances. It references previous ZAL invoices via prepayment_references. Each reference maps to a FakturaZaliczkowa element in the FA(3) XML.
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "ROZ", "invoice_date": "2026-08-17", "tax_point_date": "2026-09-17", "invoice_number": "FV2026/08/12", "description": "Settlement invoice", "customer_party_name": "Jan Kowalski", "customer_party_tax_id": "1234567890", "customer_party_address": "ul. Przykładowa 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 306899.80, "tax_amount": 22720.76, "type_operation": "goods", "prepayment_references": [ { "registration_code": "9999999999-20260215-8BEF280C8D35-4D" }, { "number": "FZ2026/03/200" } ], "tax_report_lines": [ { "position": 1, "quantity": 1, "unit_code": "C62", "description": "mieszkanie 50m^2", "price": 280177.59, "tax_code": "8", "tax_exclusive_amount": 280177.59, "tax_amount": 22414.21, "tax_inclusive_amount": 302591.80 }, { "position": 2, "quantity": 1, "unit_code": "C62", "description": "usługi dodatkowe", "price": 4001.55, "tax_code": "23", "tax_exclusive_amount": 4001.55, "tax_amount": 306.55, "tax_inclusive_amount": 4308.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 8.0, "taxable_base": 280177.59, "tax_amount": 22414.21 }, { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 4001.55, "tax_amount": 306.55 } ] } }'prepayment_references— useregistration_codefor the KSeF number (NrKSeFFaZaliczkowej) ornumberfor the invoice number (NrFaZaliczkowej) when the ZAL was issued outside KSeF.
Example: KOR_ZAL Invoice (correction of advance payment)
A KOR_ZAL corrects a previously issued ZAL invoice. Use previous_advance_total to indicate the original advance amount (P_15ZK in FA(3) XML).
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "KOR_ZAL", "amend_type": "1", "invoice_date": "2026-03-17", "tax_point_date": "2026-02-15", "invoice_number": "FK2026/03/7", "description": "Correction of advance invoice FZ2026/02/150", "amended_ksef_number": "9999999999-20260215-8BEF280C8D35-4D", "amended_date": "2026-02-15", "amended_number": "FZ2026/02/150", "customer_party_name": "Jan Kowalski", "customer_party_tax_id": "1234567890", "customer_party_address": "ul. Przykładowa 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 25000.00, "tax_amount": 4674.80, "previous_advance_total": 20000.00, "type_operation": "goods", "tax_report_lines": [ { "position": 1, "quantity": 1, "unit_code": "C62", "description": "mieszkanie 50m^2", "price": 300000, "tax_code": "23", "tax_exclusive_amount": 20325.20, "tax_amount": 4674.80, "tax_inclusive_amount": 25000.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 20325.20, "tax_amount": 4674.80 } ] } }'previous_advance_total: 20000.00— the gross total of the original ZAL being corrected (maps toP_15ZK).
Example: JST Invoice (local government unit)
An invoice addressed to a subordinate local government unit (JST). The buyer (Podmiot2) is the parent entity; the actual recipient is a Podmiot3 with role 8.
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2026-03-23", "tax_point_date": "2026-03-23", "invoice_number": "F/2026/JST/001", "description": "Services for local government unit", "customer_party_name": "Gmina Kraków", "customer_party_tax_id": "6762450871", "customer_party_address": "Plac Wszystkich Świętych 3-4", "customer_party_country": "pl", "customer_party_jst": true, "third_party_name": "Szkoła Podstawowa nr 7", "third_party_tax_id": "7654321098", "third_party_tax_scheme": "9945", "currency": "PLN", "tax_inclusive_amount": 1230.00, "tax_amount": 230.00, "type_operation": "services", "tax_report_lines": [ { "position": 1, "quantity": 10, "unit_code": "EA", "description": "Consulting services", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 1000.0, "tax_amount": 230.00 } ] } }'customer_party_jst: true— setsPodmiot2/JSTto1in the FA(3) XML.third_party_name/third_party_tax_id— the JST recipient, rendered asPodmiot3with role8.- For VAT group member invoices, use
customer_party_gv: trueinstead (role10).
Example: UPR Invoice
For UPR, the customer_party_tax_id and customer_party_country fields are required.
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "UPR", "ticket": true, "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "invoice_number": "F/2025/11/006", "description": "Sample UPR Invoice", "customer_party_tax_id": "1234567890", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 12.30, "tax_amount": 2.30, "type_operation": "goods", "tax_report_lines": [ { "position": 1, "quantity": 1, "unit_code": "EA", "description": "product 1", "price": 10.00, "tax_code": "23", "tax_exclusive_amount": 10.00, "tax_amount": 2.30, "tax_inclusive_amount": 12.30 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 10.0, "tax_amount": 2.30 } ] } }'Example: Domestic Reverse Charge Invoice
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "invoice_number": "F/2025/11/007", "description": "Construction services - reverse charge", "customer_party_name": "Example Construction Sp. z o.o.", "customer_party_tax_id": "1234567890", "customer_party_address": "Address 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 5000.00, "tax_amount": 0.00, "type_operation": "services", "tax_report_lines": [ { "position": 1, "quantity": 1, "unit_code": "EA", "description": "Construction services per contract X", "price": 5000.00, "tax_code": "oo", "tax_exclusive_amount": 5000.00, "tax_amount": 0.00, "tax_inclusive_amount": 5000.00 } ], "tax_breakdowns": [ { "name": "VAT", "category": "AE", "percent": 0.0, "taxable_base": 5000.0, "tax_amount": 0.0, "scope": "domestic" } ] } }'Example: Cross-border Reverse Charge (Services)
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "invoice_number": "F/2025/11/008", "description": "Consulting services - cross-border", "customer_party_name": "Example Company GmbH", "customer_party_tax_id": "DE123456789", "customer_party_address": "Berlin Street 1, 10115 Berlin", "customer_party_country": "de", "currency": "EUR", "exchange_rate": 4.30, "tax_inclusive_amount": 3000.00, "tax_amount": 0.00, "type_operation": "services", "tax_report_lines": [ { "position": 1, "quantity": 20, "unit_code": "HUR", "description": "IT consulting services", "price": 150.00, "tax_code": "np I", "tax_exclusive_amount": 3000.00, "tax_amount": 0.00, "tax_inclusive_amount": 3000.00 } ], "tax_breakdowns": [ { "name": "VAT", "category": "AE", "percent": 0.0, "taxable_base": 3000.0, "tax_amount": 0.0 } ] } }'Response Structure
Section titled “Response Structure”The response will include the tax report with state “sending”:
{ "tax_report": { "id": 12345, "type": "KSeF", "state": "sending", "fingerprint": "a3f2c1b9e8d7...", "identifier": "https://ksef-test.mf.gov.pl/client-app/invoice/5792000046/2025-11-07/a3f2c1b9e8d7...", "qr": "iVBORw0KGgoAAAANSUhEUgAA...", ... }}Important: Unlike traditional clearance models, B2Brouter can generate the fingerprint, identifier (QR code URL), and qr (QR code image) immediately when creating the tax report, without waiting for KSeF confirmation. This is possible because these fields are calculated from data we already have:
fingerprint: SHA-256 hash of the FA(3) XML documentidentifier: URL constructed from: supplier NIP + invoice date + fingerprint (Base64URL format)qr: QR code image encoding theidentifierURL
QR Code Label:
- While the tax report is in
sendingstate (before KSeF confirmation), the QR code label should display “OFFLINE” - Once the tax report reaches
registeredstate and you receive theto_net_id(KSeF reference number), you should display the KSeF number under the QR code instead
Best Practice: Although the QR code data is available immediately, it is recommended to wait until the tax report reaches registered state before printing/sending invoices to customers. This ensures the invoice has been successfully accepted by KSeF and avoids potential issues if the submission fails.
Check Tax Report State
Section titled “Check Tax Report State”The submission to KSeF is asynchronous. You must monitor the tax report state:
Option 1: Using Webhooks (Recommended)
Configure a tax report webhook to receive notifications when the state changes to a final state: registered or error.
Option 2: Polling
Poll the get tax report endpoint until the state is final:
curl --request GET \ --url https://api-staging.b2brouter.net/tax_reports/{TAX_REPORT_ID} \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}'Understanding the Registered State Response
Section titled “Understanding the Registered State Response”When the tax report reaches registered state, the response includes the official KSeF reference number:
{ "tax_report": { "id": 12345, "type": "KSeF", "state": "registered", "to_net_id": "1234567890-20251107-ABCD1234-EF", "fingerprint": "a3f2c1b9e8d7...", "identifier": "https://ksef-test.mf.gov.pl/client-app/invoice/1234567890/2025-11-07/a3f2c1b9e8d7...", "qr": "iVBORw0KGgoAAAANSUhEUgAA...", ... }}| Field | Available | Description |
|---|---|---|
to_net_id | After KSeF confirmation | KSeF Reference Number - The unique identifier assigned by KSeF. Display this number under the QR code on printed/PDF invoices. |
fingerprint | Immediately on creation | SHA-256 hash of the submitted FA(3) XML document. Used for document integrity verification and QR code generation. |
identifier | Immediately on creation | QR code URL - The complete URL that the QR code points to. Constructed from: supplier NIP + invoice date + fingerprint. |
qr | Immediately on creation | QR code image - Base64-encoded PNG image of the QR code. Can be embedded in invoices immediately, even before KSeF confirmation. |
Download the UPO (Official Receipt)
Section titled “Download the UPO (Official Receipt)”Once the tax report reaches registered state, you can download the UPO using the download response endpoint:
curl --request GET \ --url https://api-staging.b2brouter.net/tax_reports/{TAX_REPORT_ID}/download_response \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Accept: application/xml'Download the FA(3) XML
Section titled “Download the FA(3) XML”You can also download the complete FA(3) XML that was sent to KSeF:
curl --request GET \ --url https://api-staging.b2brouter.net/tax_reports/{TAX_REPORT_ID}/download \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Accept: application/xml'Alternatively, the xml_base64 field in the tax report response contains the XML encoded in base64.
Error Handling
Section titled “Error Handling”If the tax report reaches error state, check the tax report details for error information:
curl --request GET \ --url https://api-staging.b2brouter.net/tax_reports/{TAX_REPORT_ID} \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}'Equivalence between B2Brouter Tax Report fields and KSeF FA(3) XML nodes
Section titled “Equivalence between B2Brouter Tax Report fields and KSeF FA(3) XML nodes”The structure of the JSON format for B2Brouter tax reports is based on PEPPOL Continuous Transaction Control (CTC). The fields used in the JSON payload have different names than in the FA(3) XML representation. This is because B2Brouter Tax Report API is a universal API designed to handle tax reporting worldwide, not just KSeF.
Main Invoice Fields
Section titled “Main Invoice Fields”| B2Brouter Field | KSeF FA(3) XML Node |
|---|---|
| type | Must be “KSeF” |
| invoice_type_code | Fa > RodzajFaktury |
| invoice_date | Fa > P_1 |
| invoice_number | Fa > P_2 |
| tax_point_date | Fa > P_6 |
| customer_party_name | Podmiot2 > DaneIdentyfikacyjne > Nazwa |
| customer_party_tax_id | Podmiot2 > DaneIdentyfikacyjne > NIP (PL) or NrVatUE (EU) or NrID (non-EU) |
| customer_party_country | Podmiot2 > DaneIdentyfikacyjne > KodUE or KodKraju |
| supplier_party_name | Podmiot1 > DaneIdentyfikacyjne > Nazwa |
| supplier_party_tax_id | Podmiot1 > DaneIdentyfikacyjne > NIP |
| supplier_party_country | Podmiot1 > PrefiksPodatnika |
| description | Stopka > Informacje > StopkaFaktury |
| currency | Fa > KodWaluty |
| exchange_rate | Fa > KursWalutyZ |
| payment_date | Fa > Platnosc > TerminPlatnosci > Termin (unpaid) or Fa > Platnosc > DataZaplaty (paid) |
| payable_amount | When set to 0 with payment_date, marks invoice as paid (Zaplacono=1) |
| payment_means_type_code | Fa > Platnosc > FormaPlatnosci |
| payment_account_identifier | Fa > Platnosc > RachunekBankowy > NrRB |
| payment_service_provider_identifier | Fa > Platnosc > RachunekBankowy > SWIFT |
| amended_ksef_number | Fa > DaneFaKorygowanej > NrKSeFFaKorygowanej |
| tax_inclusive_amount | Fa > P_15 (total amount) |
| customer_party_jst | Podmiot2 > JST (1 when true, 2 when false) |
| customer_party_gv | Podmiot2 > GV (1 when true, 2 when false) |
| third_party_name | Podmiot3 > DaneIdentyfikacyjne > Nazwa |
| third_party_tax_id | Podmiot3 > DaneIdentyfikacyjne > NIP (PL), NrVatUE (EU), or NrID (non-EU) |
| purchase_order_date | Fa > WarunkiTransakcji > Zamowienia > DataZamowienia |
| despatch_advice_reference | Fa > WZ |
| supplier_contact_email | Podmiot1 > DaneKontaktowe > Email |
| supplier_contact_phone | Podmiot1 > DaneKontaktowe > Telefon |
| supplier_party_regon | Stopka > Rejestry > REGON |
| supplier_party_krs | Stopka > Rejestry > KRS |
| supplier_party_bdo | Stopka > Rejestry > BDO |
| previous_advance_total | Fa > P_15ZK (KOR_ZAL only) |
| prepayment_references | Fa > FakturaZaliczkowa (ROZ/KOR_ROZ only) |
Tax Report Lines (FaWiersz)
Section titled “Tax Report Lines (FaWiersz)”| B2Brouter Field | KSeF FA(3) XML Node |
|---|---|
| position | FaWiersz > NrWierszaFa |
| description | FaWiersz > P_7 |
| unit_code | FaWiersz > P_8A |
| quantity | FaWiersz > P_8B |
| price | FaWiersz > P_9A |
| discount_amount | FaWiersz > P_10 |
| tax_code | FaWiersz > P_12 |
| tax_exclusive_amount | FaWiersz > P_11 |
| tax_amount | FaWiersz > P_11Vat |
| ksef_amended | FaWiersz > StanPrzed (marks corrected line) |
Tax Breakdowns
Section titled “Tax Breakdowns”| B2Brouter Field | KSeF FA(3) XML Node |
|---|---|
| name | Tax scheme name (e.g., “PTU”, “VAT”) |
| category | Tax category: “S” (standard), “E” (exempt), “AE” (reverse charge) |
| percent | Tax rate percentage |
| taxable_base | P_13_x (taxable amount per rate bucket) |
| tax_amount | P_14_x (tax amount per rate bucket) |
| comment | Adnotacje > Zwolnienie > P_19A (exemption reason, when category is “E”) |
| exemption_code | P_12 override — accepts zw |
| no_subject_code | P_12 override — accepts np I, np II |
| non_exemption_code | P_12 override — accepts 0 KR, 0 WDT, 0 EX, oo |
The three *_code fields are optional. When unset, B2Brouter derives the P_12 code from category, percent, scope and type_operation. Set one of them to pin the code explicitly.
FA(3) Structure Overview
Section titled “FA(3) Structure Overview”<tns:Faktura xmlns:tns="http://crd.gov.pl/wzor/2025/06/25/13775/"> <tns:Naglowek> <tns:KodFormularza kodSystemowy="FA (3)" wersjaSchemy="1-0E">FA</tns:KodFormularza> <tns:WariantFormularza>3</tns:WariantFormularza> <tns:DataWytworzeniaFa><!-- Timestamp --></tns:DataWytworzeniaFa> <tns:SystemInfo>B2Brouter</tns:SystemInfo> </tns:Naglowek>
<tns:Podmiot1><!-- Supplier (Seller) --></tns:Podmiot1> <tns:Podmiot2><!-- Customer (Buyer) --></tns:Podmiot2>
<tns:Fa> <!-- Invoice details: currency, dates, tax amounts --> <!-- Tax breakdown totals: P_13_x, P_14_x, P_15 --> <!-- Adnotacje (annotations/flags) --> <!-- RodzajFaktury (invoice type) -->
<tns:FaWiersz><!-- Invoice line 1 --></tns:FaWiersz> <tns:FaWiersz><!-- Invoice line 2 --></tns:FaWiersz>
<tns:Platnosc><!-- Payment details (optional) --></tns:Platnosc> <tns:WarunkiTransakcji><!-- Transaction conditions (optional) --></tns:WarunkiTransakcji> </tns:Fa>
<tns:Stopka><!-- Footer/notes (optional) --></tns:Stopka></tns:Faktura>Code Descriptions for KSeF-Specific Fields
Section titled “Code Descriptions for KSeF-Specific Fields”Invoice Type Codes
Section titled “Invoice Type Codes”Param: invoice_type_code
| Code | Description | Used for |
|---|---|---|
| VAT | Basic invoice | Regular invoices |
| KOR | Corrective invoice | Corrections |
| ZAL | Advance payment invoice (Article 106f sec. 4) | Advance payments |
| ROZ | Invoice per Article 106f sec. 3 | Settlements |
| UPR | Simplified invoice (Article 106e sec. 5 item 3) | Simplified |
| KOR_ZAL | Corrective invoice for advance payment | Corrections |
| KOR_ROZ | Corrective invoice for ROZ | Corrections |
Credit Note Effect Codes
Section titled “Credit Note Effect Codes”Type of effect of correction in VAT records. Used for corrective invoices (KOR, KOR_ZAL, KOR_ROZ).
Param: credit_note_code (in Tax Report Setting)
| Code | Description |
|---|---|
| 1 | Correction with effect on the date of recognition of the original invoice |
| 2 | Correction with effect on the date of issue of the corrective invoice |
| 3 | Correction with effect on a different date (or different dates for different items) |
Tax Codes
Section titled “Tax Codes”VAT rates and categories used in Poland. Used at line level.
Param: tax_code (in tax_report_lines)
| Code | Description |
|---|---|
| 23 | Standard VAT rate 23% |
| 22 | Standard VAT rate 22% |
| 8 | Reduced VAT rate 8% |
| 7 | Reduced VAT rate 7% |
| 5 | Reduced VAT rate 5% |
| 4 | Reduced VAT rate 4% |
| 3 | Reduced VAT rate 3% |
| 0 WDT | Intra-Community Supply 0% (Wewnątrzwspólnotowa Dostawa Towarów) |
| 0 EX | Export 0% |
| 0 KR | Domestic zero-rated 0% |
| zw | Exempt from VAT (zwolniona) |
| oo | Reverse charge domestic (odwrotne obciążenie) |
| np I | Not subject to VAT - cross-border services (nie podlega) |
| np II | Not subject to VAT - domestic services |
Payment Means Codes
Section titled “Payment Means Codes”Param: payment_means_type_code
| Code | Description |
|---|---|
| 1 | Cash |
| 2 | Card |
| 3 | Bon |
| 4 | Mobile |
| 5 | Check |
| 6 | Bank transfer |
| 7 | Other |
Operation Types
Section titled “Operation Types”Param: type_operation (in Tax Report Setting)
| Code | Description |
|---|---|
| services | Services |
| goods | Goods |