Sending Invoices
ksef2 supports two sending workflows:
- Online sessions for interactive, short-lived submission.
- Batch sessions for larger sets of invoice XML files.
Both workflows encrypt invoice payloads before upload and return session references that you can use for status checks.
Online session
Section titled “Online session”Use an online session when you want to send one or a few invoices and get a KSeF number back in the same process.
from pathlib import Path
from ksef2 import FormSchema
with auth.online_session(form_code=FormSchema.FA3) as session: status = session.send_invoice_and_wait( invoice_xml=Path("invoice.xml").read_bytes(), timeout=60.0, poll_interval=2.0, ) print(status.ksef_number)The context manager closes the online session when the block exits.
Poll manually
Section titled “Poll manually”Use the lower-level calls when you need to persist the invoice reference number or attach your own retry policy.
from pathlib import Path
with auth.online_session(form_code=FormSchema.FA3) as session: result = session.send_invoice(invoice_xml=Path("invoice.xml").read_bytes()) print(result.reference_number)
status = session.wait_for_invoice_ready( invoice_reference_number=result.reference_number, timeout=120.0, ) print(status.ksef_number)Batch session
Section titled “Batch session”Use batch sessions when you need to submit many XML files as one batch. The service can prepare a package, upload all parts, close the session, and then poll until processing finishes.
from pathlib import Path
from ksef2 import FormSchema
prepared = auth.batch.prepare_batch_from_paths( invoice_paths=[ Path("invoice-1.xml"), Path("invoice-2.xml"), ], form_code=FormSchema.FA3,)
state = auth.batch.submit_prepared_batch(prepared_batch=prepared)final_status = auth.batch.wait_for_completion(session=state, timeout=300.0)print(final_status.reference_number)from pathlib import Path
from ksef2 import FormSchemafrom ksef2.domain.models import BatchInvoice
state = auth.batch.submit_batch( invoices=[ BatchInvoice( file_name="invoice-1.xml", content=Path("invoice-1.xml").read_bytes(), ), BatchInvoice( file_name="invoice-2.xml", content=Path("invoice-2.xml").read_bytes(), ), ], form_code=FormSchema.FA3,)
final_status = auth.batch.wait_for_completion(session=state, timeout=300.0)print(final_status.reference_number)Inspect results
Section titled “Inspect results”accepted = auth.batch.list_invoices(session=state)failed = auth.batch.list_failed_invoices(session=state)
print(len(accepted.invoices), len(failed.invoices))If the final status exposes an UPO reference, download the collective UPO with:
upo_xml = auth.batch.get_upo( session=state, upo_reference_number="upo-reference-from-status",)Recommended flow
Section titled “Recommended flow”-
Authenticate for the seller context.
-
Choose online or batch sending.
-
Send XML and persist returned references.
-
Poll until KSeF returns a terminal result.
-
Query metadata or download invoice XML after KSeF processing completes.