Invoice workflows usually start with the invoices command group. Use the
lower-level online and batch groups only when you need explicit session
control. Use --json when commands are part of a script or CI job.
Query metadata
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" --json \
invoices metadata \
--role seller \
--date-from 2026-01-01T00:00:00Z \
--date-to 2026-01-31T23:59:59Z \
--allUseful filters include:
--role--date-type--amount-type--seller-nip--buyer-nip--invoice-number--ksef-number--form--attachment yes|no--self-invoicing yes|no
Download one processed invoice
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
invoices download \
--ksef-number "$KSEF_NUMBER" \
--out invoice.xmlAdd --wait when the invoice may not be ready yet:
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
invoices download \
--ksef-number "$KSEF_NUMBER" \
--wait \
--timeout 120 \
--poll-interval 2Schedule and fetch an export
First schedule the export and save its decryption handle:
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" --json \
invoices export \
--role seller \
--date-from 2026-01-01T00:00:00Z \
--handle-file export-handle.jsonCheck status:
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
invoices export-status --reference "$EXPORT_REFERENCE"Fetch and decrypt the package:
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
invoices export-fetch \
--handle-file export-handle.json \
--wait \
--out-dir downloadsFor a one-command export/download flow:
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
invoices export-download \
--role seller \
--date-from 2026-01-01T00:00:00Z \
--wait \
--out-dir downloadsSend invoices
By default, invoices send opens an online session, sends the XML file, closes
the session, and prints one line per invoice:
uv run ksef2 --env test --nip "$KSEF2_NIP" --test-cert \
invoices send invoice.xmlWait for final processing and download the UPO into a directory:
uv run ksef2 --env test --nip "$KSEF2_NIP" --test-cert \
invoices send invoice.xml \
--wait \
--upo-dir uposSave a receipt when you need to check status or download the UPO later:
uv run ksef2 --env test --nip "$KSEF2_NIP" --test-cert \
invoices send invoice.xml \
--receipt invoice-receipt.json
uv run ksef2 --env test --nip "$KSEF2_NIP" --test-cert \
invoices status --receipt invoice-receipt.json --wait
uv run ksef2 --env test --nip "$KSEF2_NIP" --test-cert \
invoices upo --receipt invoice-receipt.json --out invoice-upo.xmlSend every XML file directly inside a directory:
uv run ksef2 --env test --nip "$KSEF2_NIP" --test-cert \
invoices send invoices/ --receipt-dir receiptsAdd --recursive to include nested directories. If any file fails in online
mode, the command still attempts the remaining files and exits non-zero after
printing the per-file results.
Send invoices as a batch
Use --mode batch when the input files should be prepared and submitted as one
batch session:
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
invoices send invoices/ \
--mode batch \
--wait \
--upo-dir upos \
--receipt batch-receipt.jsonA batch receipt can be reused for status and UPO downloads:
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
invoices status --receipt batch-receipt.json --wait
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
invoices upo --receipt batch-receipt.json --upo-dir uposAdvanced session commands
Session state files (--state-file, --save-state) and invoice workflow
receipt files (--receipt, --receipt-dir) carry the session AES key and IV,
so the CLI writes them with owner-only permissions (0600). Treat them like
credentials: do not commit them or paste them into issues.
Use the online group when you need to keep an online session open:
uv run ksef2 --env test --nip "$KSEF2_NIP" --test-cert \
online send invoice-1.xml invoice-2.xml \
--keep-open \
--save-state online-state.json
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
online status --state-file online-state.json
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
online close --state-file online-state.jsonUse the batch group when you need direct access to batch session state:
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
batch submit invoice-1.xml invoice-2.xml \
--wait \
--state-file batch-state.jsonCheck status or list invoices:
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
batch status --state-file batch-state.json
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
batch list --state-file batch-state.json --failedDownload a batch UPO page:
uv run ksef2 --nip "$KSEF2_NIP" --token "$KSEF2_TOKEN" \
batch upo \
--state-file batch-state.json \
--upo-reference "$UPO_REFERENCE" \
--out batch-upo.xml