This quickstart follows one TEST invoice through the SDK: build an FA(3) invoice, authenticate with a TEST certificate, send it in an online session, download the UPO, and fetch the processed invoice XML back from KSeF.
Install
Choose your preferred installation method:
Install with pip
pip install ksef2Install with uv
uv add ksef2ksef2 requires Python 3.12 or newer.
Code example
Copy the following into a quickstart.py file.
from datetime import date, datetime, timezone
from decimal import Decimal
from pathlib import Path
from ksef2 import Client, Environment, FormSchema
from ksef2.fa3 import FA3InvoiceBuilder, VatRate
SELLER_NIP = "5261040828"
DOWNLOADS = Path("downloads")
invoice_number = f"QS/{datetime.now(timezone.utc):%Y%m%d%H%M%S}"
invoice_xml = (
FA3InvoiceBuilder()
.header(system_info="ksef2 quickstart")
.seller(
name="Demo Seller Sp. z o.o.",
tax_id=SELLER_NIP,
country_code="PL",
address_line_1="Prosta 1",
address_line_2="00-001 Warszawa",
)
.buyer(
name="Demo Buyer Sp. z o.o.",
country_code="PL",
address_line_1="Kwiatowa 2",
address_line_2="00-002 Warszawa",
)
.standard()
.issue_date(date.today())
.issue_place("Warszawa")
.invoice_number(invoice_number)
.rows()
.add_line(
name="Consulting service",
quantity=Decimal("1"),
unit_price_net=Decimal("100.00"),
vat_rate=VatRate.VAT_23,
)
.done()
.done()
.to_xml()
.encode("utf-8")
)
DOWNLOADS.mkdir(exist_ok=True)
(DOWNLOADS / "generated-invoice.xml").write_bytes(invoice_xml)
with Client(Environment.TEST) as client:
auth = client.authentication.with_test_certificate(nip=SELLER_NIP)
with auth.online_session(form_code=FormSchema.FA3) as session:
submission = session.send_invoice(invoice_xml)
print(f"Sent invoice: {submission.reference_number}")
status = submission.wait(timeout=120.0)
print("Invoice status:")
print(status.model_dump_json(indent=2))
upo_xml = submission.download_upo()
(DOWNLOADS / "upo.xml").write_bytes(upo_xml)
print("Saved downloads/upo.xml")
if status.ksef_number is None:
raise RuntimeError("KSeF did not assign an invoice number.")
downloaded_xml = auth.invoices.download(status.ksef_number, timeout=120.0)
(DOWNLOADS / "processed-invoice.xml").write_bytes(downloaded_xml)
print("Saved downloads/processed-invoice.xml")Run the Python script:
python quickstart.py
# or
uv run quickstart.pyThe script writes three local files:
downloads/generated-invoice.xmldownloads/upo.xmldownloads/processed-invoice.xml
After the script completes, inspect the generated XML, the UPO, and the XML returned by KSeF. The generated and processed invoice XML should represent the same invoice; keep the processed XML as the KSeF-returned copy.
What happened
-
FA3InvoiceBuildercreated a minimal FA(3) invoice XML using public SDK field names such asinvoice_number,tax_id, andunit_price_net. -
Client(Environment.TEST)selected the TEST KSeF base URLs and owned the SDK HTTP resources. -
with_test_certificate()authenticated the TEST context represented bySELLER_NIP. -
online_session(FormSchema.FA3)opened an online session for FA(3) invoice submission. -
send_invoice()submitted the invoice and returned anInvoiceSubmissionhandle that carries the session invoice reference number. -
submission.wait()polled until KSeF assigned a KSeF invoice number. -
submission.download_upo()downloaded the UPO XML, andauth.invoices.download()fetched the processed invoice XML.
Adapt the script
Change the invoice fields or add more lines when you adapt the script. To move
the same shape into DEMO or PRODUCTION, change the root Environment and use a
credential that belongs to that environment.
For repeated local work, create a CLI-compatible profile and replace the
authentication line with client.authentication.with_profile("test-company").
Keep the profile environment aligned with the root client environment.
Related pages
- Client setup: Create sync and async clients and manage their lifecycle.
- Authentication guide: Authenticate with a token, XAdES certificate, TEST certificate, or profile.
- Use profiles: Use a CLI-compatible local profile after the first TEST run.
- Build FA(3) invoices: Generate valid FA(3) invoice XML with the fluent builder.
- Sending invoices: Send invoices online or in batch and track processing state.
- Downloading invoices: Download invoice XML directly or through export packages.
- Public API contract: Review stable public imports for application code.
