eliDocs
Country Guides

Poland

Polish e-invoicing: the KSeF FA(3) invoice checked against the Ministry of Finance XSD, the builder's narrow scope, and the KSeF submission boundary.

Poland’s e-invoicing mandate is already live. Invoices go through KSeF (Krajowy System e-Faktur), the central clearance platform run by the Ministerstwo Finansów (MF), in the national FA(3) structured-invoice format. FA(3) is Poland’s own XML schema, not EN 16931 UBL or CII. The authority hub is ksef.podatki.gov.pl.

Beliq generates and validates FA(3) with the Schema-checked badge: the MF publishes the XSD but no machine-readable business rules, because KSeF checks them itself at submission. The format is provisional. The generator covers ordinary VAT invoices in PLN between Polish parties; the FA(3) format reference lists exactly what it builds and what it refuses.

Where Beliq fits

Where Beliq fits

  • Generate FA(3) via standard: "ksef" (profile fa3, the default). Ordinary VAT invoices only (RodzajFaktury VAT), PLN only, VAT rates 23, 22, 8, 7 and 5, a Polish seller NIP, and a Polish buyer NIP or no buyer identifier. Corrections, advance invoices, credit notes and zero-rated, exempt or reverse-charge lines are refused with a 422 rather than built wrongly.
  • Validate FA(3) against the MF’s XSD with format=poland_ksef_fa3 on POST /v1/validate, or let auto-detect match the FA(3) namespace. The response carries verificationTier: "xsd-structural".
  • FA(2) is recognised, never passed. FA(3) replaced FA(2) on 2026-02-01 and KSeF rejects FA(2), so an FA(2) document comes back valid: false with a POLAND_KSEF_FA2_SUPERSEDED error.
What Beliq does NOT do (KSeF boundary)

What Beliq does NOT do (KSeF boundary)

KSeF has no accredited operator or intermediary role that a service like Beliq could hold: the relationship is between each taxpayer and the MF. Beliq does not:

  • Submit invoices to KSeF, interactively or in batches, or open KSeF sessions.
  • Authenticate against KSeF with a KSeF token or certificate, or hold either for you.
  • Sign or encrypt the submission, or apply the KSeF number to your invoice.
  • Fetch, store or match the UPO receipts.
  • Handle offline24 or emergency-mode invoicing.
  • Archive invoices or UPOs.

Hand Beliq’s FA(3) output to whatever submits for you. Everything after the XML is outside Beliq.

Mandate is live today, not a phase-in

Mandate is live today, not a phase-in

If you issue invoices in Poland, you are already in mandate scope:

  • From 2026-02-01 for companies whose 2024 sales, VAT included, exceeded PLN 200 million.
  • From 2026-04-01 for everyone else.
  • Until 2026-12-31, invoices may still be issued outside KSeF in a month where their total, VAT included, stays at or below PLN 10,000.
  • Penalties for KSeF errors are deferred to 2027-01-01.

Last verified against the MF's KSeF hub page on when invoices must be issued in KSeF (modified 30 April 2026) and its KSeF 2.0 Q&A on 29 September 2026. Official source.

Your KSeF submission channel has to be live the day your Beliq integration goes live.

Integration architecture (Beliq vs KSeF)

Integration architecture (Beliq vs KSeF)

Concern In Beliq today Outside Beliq (your stack / partner)
FA(3) structured invoice Generate, Validate n/a
KSeF session, authentication, submission Not offered Your intermediary or your own KSeF integration
KSeF number and UPO receipt Not offered Your intermediary
Retention of invoices and UPOs Not offered You or your intermediary
Generating a Polish invoice

Generating a Polish invoice

Both parties carry a Polish NIP in vatId (with or without the PL prefix). Send currencyCode: "PLN" and one of the five supported VAT rates on every line. The optional invoice.poland block sets FA(3) fields with no EN 16931 source, such as the place of issue and the Adnotacje markers; every one has a default.

generate-poland-ksef-fa3.sh
curl -X POST https://api.beliq.eu/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "standard": "ksef",
    "output": "xml",
    "invoice": {
      "number": "FA/2026/10/0001",
      "issueDate": "2026-10-01",
      "currencyCode": "PLN",
      "seller": {
        "name": "Dostawca Sp. z o.o.",
        "vatId": "PL1080109261",
        "address": {
          "street": "ul. Przykładowa 1",
          "city": "Warszawa",
          "postalCode": "00-001",
          "countryCode": "PL"
        }
      },
      "buyer": {
        "name": "Odbiorca Sp. z o.o.",
        "vatId": "PL5261040828",
        "address": {
          "street": "ul. Testowa 2",
          "city": "Kraków",
          "postalCode": "30-001",
          "countryCode": "PL"
        }
      },
      "lines": [
        {
          "description": "Usługi doradcze",
          "quantity": 10,
          "unitCode": "HUR",
          "unitPrice": 100,
          "lineTotal": 1000,
          "vatRate": 23,
          "vatCategoryCode": "S"
        }
      ],
      "taxSummary": [
        { "vatCategoryCode": "S", "vatRate": 23, "taxableAmount": 1000, "taxAmount": 230 }
      ],
      "totalNetAmount": 1000,
      "totalTaxAmount": 230,
      "totalGrossAmount": 1230,
      "poland": { "placeOfIssue": "Warszawa" }
    }
  }'

The builder writes the parties, the lines, the VAT summary slots and the gross total. The totals you send must match what the lines give, with the VAT taken once per rate on the summed net, or the request is refused with a 400. Payment terms (dueDate, paymentMeans), references and notes are not carried into FA(3), and document-level allowances and charges are not supported.

Validation behaviour

Validation behaviour

  • XSD and KSeF acceptance checks. There is no Schematron layer. Structural failures carry ruleId: "XSD". The document-level checks the MF lists for KSeF (encoding, processing instructions, discouraged characters, size) carry KSEF_* rule IDs, listed in the format reference. A clean pass means the document matches the FA(3) schema and those checks, not that KSeF will accept it: KSeF applies its business rules at submission.
  • Response metadata. A detected FA(3) reports format: "poland_ksef_fa3", profileDetected: "poland-ksef-fa3-13775", polandKsefFa3XsdBundle and polandKsefFa3RuntimeVersion. See the validation artifacts page for the pin.
Further reading

Further reading