The root Client owns HTTP transport configuration and exposes unauthenticated
public branches. Authenticate once for a KSeF context, then pass the
authenticated client into workflow code.
Choose sync or async
Client is the synchronous root client and AsyncClient is its async twin.
They expose the same API; with AsyncClient you use async with and await
the calls.
Sync
from ksef2 import Client, Environment
with Client(Environment.TEST) as client:
auth = client.authentication.with_test_certificate(nip="5261040828")Async
from ksef2 import AsyncClient, Environment
async with AsyncClient(Environment.TEST) as client:
auth = await client.authentication.with_test_certificate(nip="5261040828")Use Environment.DEMO or Environment.PRODUCTION outside local TEST
workflows.
Manage lifecycle
The root client owns SDK-managed HTTP resources. Prefer a context manager for scripts and jobs:
from ksef2 import Client, Environment
with Client(Environment.TEST) as client:
auth = client.authentication.with_test_certificate(nip="5261040828")If a framework asks for a yielded dependency, put the yield inside the
dependency function and close the client in finally:
from collections.abc import Iterator
from ksef2 import Client, Environment
def get_client() -> Iterator[Client]:
client = Client(Environment.TEST)
try:
yield client
finally:
client.close()Async applications use the same boundary with async with:
from ksef2 import AsyncClient, Environment
async with AsyncClient(Environment.TEST) as client:
auth = await client.authentication.with_test_certificate(nip="5261040828")Online and batch sessions are lifecycle boundaries too. Use a session context manager so the SDK closes the remote session when the block exits:
from ksef2 import FormSchema
with auth.online_session(form_code=FormSchema.FA3) as session:
status = session.send_invoice(invoice_xml).wait()When credentials live in a CLI-compatible profile, create the root client for
the profile environment and authenticate through with_profile():
from ksef2 import Client, Environment
client = Client(Environment.PRODUCTION)
auth = client.authentication.with_profile("prod-token")Public root branches
The root client is useful before authentication:
certificates = client.encryption.get_certificates()
providers = client.peppol.list().first_page()The TEST-only branch is also on the root client:
client.testdata.create_subject(
nip="5261040828",
subject_type="vat_group",
description="Sandbox company",
)Authenticated branches
After authentication, use the branch that matches the task:
invoices = auth.invoices
batch = auth.batch
tokens = auth.tokens
permissions = auth.permissions
certificates = auth.certificates
limits = auth.limits
sessions = auth.sessions
invoice_sessions = auth.invoice_sessionsRecommended flow
-
Read environment and transport settings in your application boundary.
-
Create one root client for the selected KSeF environment.
-
Use root branches only for public lookup or TEST data setup.
-
Authenticate once for the context that owns the operation.
-
Pass the authenticated client to invoice, token, permission, certificate, limits, and session workflows.
Reference
- Authentication guide: Authenticate with a token, XAdES certificate, TEST certificate, or profile.
- Operations: Map common workflows to high-level SDK entry points.
- Configure a certificate store: Configure certificate cache refresh or provide a custom certificate store.
- Encryption certificates: Inspect KSeF public encryption certificates before encrypted workflows.
- PEPPOL providers: Query public PEPPOL provider data from the root client.
- TEST data: Create and manage TEST subjects and permissions.
- Client lifecycle: Review root client lifecycle, authenticated clients, and close behavior.
