Skip to main content

Introduction

KSeF (Krajowy System e-Faktur) 2.0 is Poland’s mandatory national e-invoicing system operated by the Ministry of Finance. The system uses the FA(3) XML schema format for structured invoice data and provides real-time clearance for all B2B invoices. Invoices are encoded in FA(3), a strict XML format that enforces standardized fields for domestic and cross-border transactions. The KSeF system validates all submitted invoices in real-time and assigns a unique KSeF ID upon successful clearance. This guide covers two key processes: For registering parties (suppliers) in the KSeF system, see the companion guide: Poland: Supplier registration. Invopop supports two use cases that require different configurations:
  • Send only: You issue invoices through KSeF on behalf of your suppliers. This is the simplest setup and does not require the Cron app or import/sync workflows.
  • Send & receive: In addition to sending, you also want to automatically import invoices received by your suppliers from KSeF. This requires the Cron app to periodically check for new invoices.
The table below summarizes which components are needed for each use case:

Prerequisites

To issue invoices through KSeF, you will need:
  • A registered party (supplier): follow the KSeF supplier registration guide to connect the Poland app and register the party with KSeF before issuing.
  • Customer details, including their Polish Tax ID (NIP) for domestic B2B invoices.
  • Line items with quantities, prices, and applicable VAT rates.

Setup

All of the following steps must be carried out from the Invopop Console.
The Poland app must already be connected and the party registered with KSeF — both are covered in the supplier registration guide.
1

Configure the invoice sending workflow

This workflow signs the GOBL document, converts it to FA(3) XML, and submits it to KSeF.

KSeF send invoice workflow

Add to my workspace →
2

Connect the Cron app

You can skip this and the following steps if you only need to send invoices (send only use case).
  1. Navigate to ConfigurationApps
  2. Find Cron in the app discovery list
  3. Click Connect to activate
No additional configuration is needed. The Cron app handles scheduling periodic workflow execution for importing received invoices.
3

Configure the invoice import workflow

This workflow imports an individual invoice from KSeF when it is received. It is automatically triggered by the sync workflow (configured in the next step) for each invoice found.

KSeF import invoice workflow

Add to my workspace →
4

Configure the invoice sync workflow

This workflow syncs all received invoices for a party within a specific time range. It creates an import job for each invoice found, using the import workflow you configured in the previous step.Configure the Sync received invoices from KSeF step to reference the import workflow created in the previous step.
Configure the workflow that all invoices will be sent to

KSeF sync received invoices workflow

Add to my workspace →
For the send & receive use case, parties must be registered with the send & receive variant of the registration workflow, which subscribes them to periodic invoice imports via the Cron app. See the supplier registration guide for details.

Running

In this section, we’ll provide details on how to issue invoices on behalf of a registered party and how to import received invoices.

Send an invoice

Once a party is registered, you can issue invoices on their behalf. The following examples show partial GOBL documents you can copy and paste directly into the Invopop Console or store via the API as silo entries.
GOBL Invoices sent to KSeF require the regime set to PL and addons must include pl-favat-v3 for FA(3) schema compliance.
In this example, we’re issuing a standard B2B invoice from a Polish supplier to another Polish business customer.Notice:
  • the minimal version in the first tab contains only the essential fields required to create the invoice,
  • the pl-ksef-v1 addon ensures the document will be validated using the KSeF rules built into the GOBL library,
  • there are no totals or calculations in the minimal version; all these will be calculated automatically when running gobl build,
  • the built version in the second tab shows the normalized document with calculated totals, line item sums, tax breakdowns, and automatically generated fields like i (line index), sum, and total, and,
  • make sure to process it with the “KSeF issue invoice” workflow created during setup.
In this example, we’re issuing a reverse charge invoice from a Polish supplier to a customer in another EU member state.Notice:
  • the customer has a valid EU VAT ID, indicating the transaction is subject to reverse charge mechanism,
  • the minimal version contains only essential fields; totals and tax calculations are omitted,
  • when running gobl build, the system automatically calculates totals, applies reverse charge rules, and normalizes the document,
  • the built version shows all calculated fields including the reverse charge indicator, tax breakdowns, and final totals, and,
  • the invoice is validated using the KSeF rules to ensure compliance with Polish e-invoicing requirements.
In this example, we’re issuing a credit note to correct or refund a previous invoice.Notice:
  • the type field is set to credit-note to indicate this is a corrective document,
  • the preceding field references the original invoice being corrected,
  • the minimal version contains only the essential fields; calculations are handled by GOBL,
  • when running gobl build, the system automatically calculates negative totals, tax refunds, and validates the credit note structure,
  • the built version shows all calculated fields including negative amounts for the refund, and,
  • the document is validated using the KSeF rules to ensure compliance with Polish credit note requirements.
In this example, we’re issuing a prepayment invoice to document an advance payment received before completing the delivery of goods or services.Notice:
  • the $tags field includes partial, which tells the FA_VAT addon to classify this as a ZAL (Faktura Zaliczkowa) document type,
  • the payment.advances array records the advance payment details, including the mandatory date field and a percent of the total,
  • GOBL automatically calculates the advance amount from the percentage and deducts it from the payable total to produce the due amount,
  • the built version shows "pl-favat-invoice-type": "ZAL" automatically set in the tax extensions, and,
  • after sending this invoice through KSeF, reference the assigned KSeF number in the subsequent settlement invoice.
In this example, we’re issuing a settlement invoice to finalize a transaction after one or more advance payments have been made.Notice:
  • the $tags field includes settlement, which tells the FA_VAT addon to classify this as a ROZ (Faktura Rozliczeniowa) document type,
  • the preceding field references the original prepayment invoice, including its KSeF number stamp,
  • the payment.advances array records the previously paid advance amount, which GOBL deducts from the total to calculate the remaining due,
  • the line items represent the full value of the delivered goods or services, and,
  • the built version shows "pl-favat-invoice-type": "ROZ" automatically set in the tax extensions.
B2C invoices are excluded from the mandatory e-invoicing requirement. The tax authority already receives B2C sales data through online fiscal cash registers that transmit receipts to the Central Repository of Cash Registers (CRK). However, businesses may voluntarily issue B2C invoices through KSeF.
A self-billed invoice (samofakturowanie) is issued by the customer on behalf of the supplier, under a prior agreement between the two parties.
After creating the invoice in the Console:
  1. Click Build to validate
  2. Click Save to store in the silo
  3. Click Select workflow and choose the KSeF Send Invoice workflow
  4. Click Run workflow
The invoice will be validated, converted to FA(3) XML format, and sent to KSeF. Upon successful clearance, it will receive a unique KSeF ID.
For international transactions, the invoice is created and cleared in KSeF just like domestic invoices. Because the foreign recipient cannot log into KSeF, delivery happens outside the platform (via email, EDI, etc.) with the KSeF QR code included for verification.

Import received invoices

This section only applies if you configured the send & receive setup. If you only need to send invoices, you can skip this section entirely.
Once you’ve configured the import and sync workflows, and registered parties with the send & receive registration workflow, the Cron app automatically triggers the sync workflow at the interval configured in the registration workflow’s Subscribe to periodic KSeF sync step. Here is how it works:
  1. Cron scheduling: The Cron app creates a job for the sync workflow at each configured interval, passing the time window (from and upto) to process
  2. Sync workflow: The sync workflow queries KSeF for all invoices received within the time window
  3. Import jobs: For each invoice found, a job is created using your import workflow
  4. Import workflow: Each job downloads the FA(3) XML from KSeF, converts it to GOBL format, and stores it in your Invopop silo
  5. Organization: Imported invoices are automatically placed in the configured folder (typically “Invoices · Expenses”) with a Registered state
Each party is subscribed to periodic imports during registration when using the receive registration workflow. To use a different interval for a specific party, adjust the Subscribe to periodic KSeF sync step settings in the registration workflow before running it.

Manual import

If you need to import invoices outside of the automatic cron schedule, you can manually trigger imports from the Console or via the API. Import a single invoice To import a specific invoice from KSeF, you need:
  • KSeF Number: The unique invoice identifier (e.g., 1234567890-20260120-ABCD1234-EF)
  • Supplier NIP: The Polish Tax ID of the invoice issuer
  1. Navigate to Workflows and find your KSeF Import Invoice workflow
  2. Click Run from the workflow editor or the ... menu in the workflow list (see Running from the Console)
  3. Leave the document field empty — the import workflow will create a new silo entry automatically
  4. Fill in the Arguments:
  1. Click Run workflow
The invoice will be downloaded from KSeF, converted to GOBL, and stored in your silo. Import multiple invoices by date range To import all invoices received within a specific time period, you need:
  • The party silo entry for the supplier whose invoices you want to sync
  • The date range (from and upto) to process
  1. Navigate to Workflows and find your KSeF Sync Received Invoices workflow
  2. Click Run from the workflow editor or the ... menu in the workflow list
  3. In the Select a document field, search for and select the party (supplier) entry
  4. Fill in the Arguments:
  1. Click Run workflow
The sync workflow will query KSeF for all invoices received in that date range and create individual import jobs for each invoice found.
Use single invoice import to bring in a specific invoice immediately after receiving notification from a supplier. Use date range sync to backfill invoices or to import historical invoices from before the cron subscription was active.

Error handling and notifications

We strongly recommend adding notification steps to your workflows to alert you of import failures:
  • In the import workflow: Add email or Slack notifications to the error handling section
  • In the sync workflow: Add notifications for when the sync process encounters issues
This ensures you’re immediately aware if invoices fail to import, allowing you to take corrective action.
Common import issues include certificate expired or invalid, KSeF API temporarily unavailable, invoice format not supported by GOBL conversion, and network connectivity issues. Check your workflow error logs in the Console for detailed error messages.

GOBL addon reference

Detailed information about the FA(3)-specific extensions and validations can be found in: You can also use the GOBL Builder to create custom invoices with the Polish regime and FA(3) addon.

FAQ

International (cross-border) invoices are handled just like domestic invoices in KSeF:
  • The invoice is created in GOBL with the foreign recipient’s details
  • It’s converted to FA(3) XML format and submitted to KSeF
  • KSeF validates and clears the invoice, assigning a unique KSeF ID
  • The invoice is registered in the KSeF system
However, since foreign recipients cannot access KSeF, you must deliver the invoice through other channels (email, EDI, etc.). Include the KSeF QR code in the delivery for verification purposes.
Test mode (sandbox only): Uses self-signed certificates generated automatically by Invopop. Perfect for quick testing without accessing the KSeF portal. Invoices are not sent to real KSeF servers.Demo mode (sandbox only): Connects to the official KSeF Demo Portal. Requires manual certificate generation, simulating the full production flow in a safe test environment.Production mode (live workspace): Connects to the live KSeF Portal. Requires valid company credentials and certificates. All invoices are submitted to the official KSeF system.
Use test mode for initial integration testing, then switch to demo mode when you’re ready to simulate the real certificate flow before going live.
Official KSeF applications:For testing:
Install the KSeF Poland app, register your supplier (Test, Demo, or Production environment), and run invoices through the Send Invoice workflow. Each environment requires its own NIP and certificate setup.
This error means the uploaded KSeF certificate does not have the required permissions to issue invoices. This typically happens when the certificate was uploaded by someone who is not the company administrator and only has limited permissions granted by the main company account.The KSeF certificate uploaded to Invopop must belong to either:
  • The company account directly logged into KSeF, or
  • An entity that has both InvoiceRead and InvoiceWrite permissions (managed within KSeF)
To resolve this, you have two options:
  1. Grant permissions in KSeF: The company admin (or whoever has direct access to the KSeF company account) grants InvoiceRead and InvoiceWrite permissions to the user who uploaded the certificate to Invopop. This can be done from the KSeF application portal and requires no further action in Invopop (no need to unregister/register).
  2. Re-register with a new certificate: Unregister the supplier in Invopop and register it again using a certificate generated from the main KSeF company account (or another account with the required permissions).
See the Poland tax regime in GOBL for tax categories and NIP rules. The pl-favat-v3 addon documents the FA(3) schema fields required for KSeF.
Polish invoicing law requires a unit of measure for every line, and KSeF maps it to the P_8A field on each FaWiersz. Invopop supports two ways to populate it:
  1. Canonical unit code on Item.Unit — preferred when the unit exists in the GOBL unit catalogue or as a UN/ECE Recommendation 20 code. For example, Item.Unit: "H87" (piece) or Item.Unit: "KGM" (kilogram). The gobl.ksef converter emits the UN/ECE code directly into P_8A.
  2. Free-form label on Item.Meta["unit-label"] — use this for Polish abbreviations that do not match a canonical code, such as "szt." (sztuka — piece), "usł." (usługa — service), "kpl." (komplet — set) or "opak." (opakowanie — package). The value is passed through to P_8A unchanged, so the supplier’s exact wording is preserved on the KSeF XML.
Example line item using a free-form label:
When an inbound KSeF invoice contains a P_8A value that is not a recognised GOBL or UN/ECE code, gobl.ksef preserves the original string under Item.Meta["unit-label"] so round-trips do not lose the supplier’s wording. Item.Unit is only populated when the value validates as a canonical code.
More available in our Poland FAQ section

Participate in our community

Ask and answer questions about invoicing in Poland →