FA(3) XML

FA(3) XML: how to generate and validate it

FA(3) is the XML schema every invoice sent to KSeF must follow. This guide covers its structure, how to validate it against the official XSD, the errors that usually break it, and how to get valid FA(3) XML from plain JSON.

Updated 7 min read

What FA(3) is

FA(3) is the third version of the logical structure of the Polish structured invoice (e-Faktura), published by the Ministry of Finance as an XSD. Since KSeF 2.0, every invoice sent to KSeF has to be valid FA(3) XML. In KSeF the XML is the invoice; a PDF is only a visualisation of it.

Every FA(3) document starts with the same header:

invoice.xmlFA (3) · 1-0E
<Faktura xmlns="http://crd.gov.pl/wzor/2025/06/25/13775/">
  <Naglowek>
    <KodFormularza kodSystemowy="FA (3)" wersjaSchemy="1-0E">FA</KodFormularza>
    <WariantFormularza>3</WariantFormularza>
    <DataWytworzeniaFa>2026-10-12T07:23:07Z</DataWytworzeniaFa>
  </Naglowek>
  <!-- Podmiot1 (seller), Podmiot2 (buyer), Fa (invoice data) -->
</Faktura>

Structure of an FA(3) invoice

A standard VAT invoice uses four main blocks. The table shows where each field of a Notaly POST /invoices request ends up.

FA(3) elementContainsFrom JSON field
NaglowekForm code, schema version, creation timestampGenerated
Podmiot1Seller: NIP, Nazwa, Adresseller
Podmiot2Buyer: NIP, Nazwa, Adresbuyer
Fa/KodWalutyCurrency (ISO 4217)currency
Fa/P_1Issue dateissueDate
Fa/P_2Invoice numbernumber
Fa/P_13_x, P_14_xNet and VAT totals per rate (23%, 8%, 5%, 0%)Computed from items
Fa/P_15Gross totalComputed
Fa/AdnotacjeMandatory annotations (split payment, exemptions, margin scheme…)Generated defaults
Fa/FaWierszLine items: P_7 name, P_8A unit, P_8B quantity, P_9A unit net price, P_11 net value, P_12 VAT rateitems[]

How to validate FA(3) against the XSD

Validate locally before you send anything to KSeF. Download the official FA(3) schema from the Ministry of Finance (the main schemat.xsd imports shared type definitions, so keep all the files in one folder) and run:

terminal
xmllint --noout --schema schemat.xsd invoice.xml
# invoice.xml validates

XSD validation catches structure and type errors. KSeF also runs business checks after the XSD, so a schema-valid file can still be rejected. Notaly validates every invoice against the XSD before submitting it and returns KSeF rejections as stable error codes.

Common FA(3) validation errors

  • Invalid NIP. A NIP has 10 digits and a checksum (weights 6, 5, 7, 2, 3, 4, 5, 6, 7 modulo 11). A typo fails before KSeF even sees the invoice.
  • Totals that do not add up. P_13_x and P_14_x have to equal the sum of the lines for each VAT rate, and P_15 the gross total, rounded to 2 decimals.
  • Wrong date or currency format. Dates are YYYY-MM-DD, currencies ISO 4217 (PLN, EUR), countries ISO 3166 alpha-2 (PL).
  • Missing annotations. Adnotacje is mandatory even when nothing special applies: every flag (P_16, P_17, P_18, P_18A, P_23…) must be set explicitly.
  • Old namespace. FA(2) files use a different namespace and are not accepted as FA(3).
  • Unescaped characters. Names with &, < or quotes must be XML-escaped.

Generate FA(3) XML from JSON

With Notaly you do not write FA(3) by hand. Send the invoice as JSON and Notaly computes totals per VAT rate, fills in the header and annotations, escapes the text, validates the result and submits it to KSeF.

  1. Create the invoiceSend POST /invoices with seller, buyer and items, as in the KSeF API example.
  2. Download the exact XMLCall GET /invoices/{id}/xml to get the FA(3) document that was sent to KSeF, byte for byte.
  3. Keep the proofWhen the invoice is accepted, store the KSeF number and the UPO, and share the PDF with the KSeF QR code with your customer.
GET/invoices/{id}/xml200 application/xml
curl https://api.getnotaly.com/invoices/inv_8f2c…/xml \
  -H "Authorization: Bearer $NOTALY_API_KEY" -o invoice.xml

Frequently asked questions

What is FA(3)?

FA(3) is the third version of the logical structure of a structured invoice (e-Faktura) published by Poland's Ministry of Finance. It is the XSD that KSeF 2.0 validates every invoice against.

What namespace does FA(3) use?

http://crd.gov.pl/wzor/2025/06/25/13775/ with KodFormularza kodSystemowy="FA (3)" and wersjaSchemy="1-0E".

How do I validate FA(3) XML?

Validate it against the official FA(3) XSD (for example with xmllint --schema) before sending. Notaly validates every invoice against the XSD before it is submitted to KSeF.

Can I send my own FA(3) XML to Notaly?

Today Notaly generates FA(3) from JSON via POST /invoices, and you can download the exact XML that was sent with GET /invoices/{id}/xml.

Is the PDF the legal invoice?

No. In KSeF the FA(3) XML is the invoice. The PDF Notaly produces is a human-readable visualisation with the KSeF verification QR code (KOD I).

Issue your first KSeF test invoice today

Create a sandbox account: API key in seconds, 3 free test invoices on KSeF TEST, no credit card.