Small Go CLI for working with the Polish KSeF API.
This repository is published as a working reference project and personal PoC. It is not a polished end-user product. PRs are not being accepted.
The CLI covers the bootstrap auth flow and the regular invoice flow:
- initialize local settings
- request an auth challenge and generate unsigned XML
- submit a signed XAdES XML document
- poll auth status and redeem access and refresh tokens
- generate and store a reusable KSeF token
- authenticate with the saved KSeF token
- list invoice metadata
- download invoice XML files
- render invoice PDFs
- export invoice metadata to CSV
Local settings and tokens are stored in ~/.ksef/settings.json.
Build a local binary:
go build -o bin/ksef .Run tests:
go test ./...Install the binary and shell completions:
make installBy default make install writes:
- the binary to
~/.local/bin/ksef - bash completion to
~/.local/share/bash-completion/completions/ksef - zsh completion to
~/.local/share/zsh/site-functions/_ksef - fish completion to
~/.config/fish/completions/ksef.fish
You can override those paths:
make install INSTALL_DIR=$HOME/bin
make install ZSH_COMPLETION_DIR=$HOME/.zsh/completionsFor zsh, make sure ~/.local/share/zsh/site-functions is on fpath and compinit is enabled.
Generate completion files without installing them:
make completionsYou can also use Cobra directly:
ksef completion bash
ksef completion zsh
ksef completion fishInitialize or update local settings:
ksef init --nip <NIP> --environment testThe CLI keeps all local path defaults in ~/.ksef/settings.json. You can set them during init and still override them per command later.
Relevant init flags:
--nip--environment demo|test|production--base-url--subject-identifier-type certificateSubject|certificateFingerprint--verify-certificate-chain--auth-request-file--signed-auth-request-file--download-dir--pdf-dir--export-dir
Default local paths are:
- unsigned auth XML:
./auth_request.xml - signed auth XML:
./signed_auth_request.xml - invoice XML downloads:
./invoices - rendered PDFs:
./invoice-pdfs - CSV exports:
./exports
Example:
ksef init \
--nip <NIP> \
--environment test \
--download-dir "$HOME/Documents/ksef/xml" \
--pdf-dir "$HOME/Documents/ksef/pdfs" \
--export-dir "$HOME/Documents/ksef/csv"The code defaults to the demo environment unless you set another one.
The CLI supports two auth paths.
Use this once to get short-lived access and refresh tokens. Then generate a reusable KSeF token.
Step 1. Request a challenge and write unsigned XML:
ksef challengeOr override the output path explicitly:
ksef challenge -o /tmp/auth_request.xmlStep 2. Sign the XML outside the CLI. The project does not sign XAdES documents itself. You need to sign the generated XML with your certificate or trusted signing tool and produce a signed XML file.
Step 3. Submit the signed XML:
ksef authorizeOr override the input path explicitly:
ksef authorize -f /tmp/signed_auth_request.xmlStep 4. Poll auth status until it completes:
ksef get-auth-status --waitStep 5. Redeem the auth token for access and refresh tokens:
ksef redeemStep 6. Generate a reusable KSeF token for later use:
ksef generate-tokenUseful auth flags:
ksef authorize --verify-certificate-chain
ksef get-auth-status --wait --timeout 60s
ksef redeem --authenticationToken <token>After generate-token, the CLI can authenticate with the saved token and refresh access automatically.
You can run the token auth flow directly:
ksef token-authOr just run a normal command. If the access token is missing or expired, the CLI falls back to refresh or token auth automatically.
You can also force a refresh explicitly:
ksef refreshList purchase invoices for a month:
ksef list-invoices -m 2026-04
ksef list-invoices -m 2026-04 -o json
ksef list-invoices -m 2026-04 -o csvList last month for purchase and sales:
ksef list-last-month --subject bothDownload invoice XML files. The command uses the configured default download directory unless you pass --dir:
ksef download -m 2026-04
ksef download -m 2026-04 -d ./invoicesRender PDFs. The command uses the configured default PDF directory unless you pass --dir:
ksef download-pdfs -m 2026-04 --subject both
ksef download-pdfs -m 2026-04 --subject both -d ./invoice-pdfs
ksef download-last-month-pdfs --subject purchaseExport invoice metadata to CSV. The command uses the configured default export directory unless you pass --dir:
ksef export-csv -m 2026-04 --subject both
ksef export-csv -m 2026-04 --subject both -d ./exportsPDF rendering uses Chrome or Chromium through chromedp.
If Chrome is not found automatically, set one of these environment variables:
export KSEF_CHROME_PATH=/path/to/chrome
# or
export CHROME_PATH=/path/to/chromeThe tool writes these local outputs by default:
./invoices/./invoice-pdfs/./exports/./bin/when you build locally
The repository .gitignore covers those default generated output locations and .DS_Store.
The default auth XML filenames ./auth_request.xml and ./signed_auth_request.xml are ignored by the repository .gitignore.
Custom auth XML paths are user-managed and are not ignored automatically.
Start here if you want to inspect the implementation.
main.go wires the Cobra CLI and registers all commands.
internal/settings/settings.go handles local settings persistence in ~/.ksef/settings.json, including configurable output paths.
internal/ksef.go contains the KSeF client, request and response types, XML generation, token encryption, and invoice download helpers.
The XAdES bootstrap auth path lives in these files:
commands/challenge.gocommands/authorize.gocommands/get_auth_status.gocommands/redeem.go
The reusable KSeF token path lives in these files:
commands/generate_token.gocommands/token_auth.gocommands/refresh.gocommands/common.go
Invoice listing and export logic lives in:
commands/list_invoices.gocommands/list_last_month.gocommands/download.gocommands/download_pdfs.gocommands/export_csv.gointernal/render/
Before publishing or sharing a working tree, remove any local XML, PDF, CSV, and binary artifacts. Do not publish real NIP values, signed XML files, access tokens, refresh tokens, KSeF tokens, or downloaded invoices.