The problem
What problem does KSeF e-invoicing solve?
From February 2026 Polish businesses stop sending domestic invoices as PDFs. They file them with KSeF, the Ministry of Finance's national e-invoicing system. An invoice counts only once KSeF accepts it and issues a receipt, the UPO.
If your booking, rental or subscription system issues invoices, this becomes part of your software. Every invoice has to be encrypted, sent to the ministry's API, checked for acceptance and stored with its KSeF number and receipt. Purchase invoices come back the same way.
Three things make this harder than a normal API. There is no official TypeScript library, only C# and Java. KSeF never calls your system back, so everything is submit and poll. And nothing in the API checks that the invoice belongs to your company. A mistake files a binding tax document under the wrong taxpayer.
This skill gives a coding agent the rules and the code to build that integration into a Next.js app on Vercel, the way we build it, with those three problems handled by design.
The module
What does the skill build?
An agent with this skill builds one module for a Next.js App Router app, on your stack. For KSeF e-invoicing that module consists of:
- 1. Token auth
- 2. Invoice encryption
- 3. Interactive and batch sending
- 4. UPO receipts
- 5. Purchase-invoice sync
- 6. QR codes
What it needs from you
- A Next.js App Router app on Vercel, since the patterns assume serverless functions, Vercel Cron, and a database (Neon/Supabase Postgres or equivalent)
- A KSeF token for the target environment; the one-time bootstrap on TEST and production is documented in
references/errors-limits-and-testing.md - Env vars
KSEF_BASE_URL,KSEF_KSEF_TOKEN,KSEF_CONTEXT_NIPto get started, plusKSEF_CREDENTIALS_ENCRYPTION_KEYandCRON_SECRETonce credentials live in the database and crons run, all of them documented inreferences/architecture-and-vercel.md
Provenance
Where do the rules come from?
This skill is written by the engineer who has shipped this integration, a KSeF invoicing module in a Next.js app on Vercel, starting from the Ministry of Finance's own API 2.0 specification and corrected against the official C# and Java clients, the live OpenAPI and what integrating it taught us. The references hold four properties: the seller NIP is compared to the authenticating context before every send, the raw ciphertext is uploaded with the IV carried once in the session metadata, a440duplicate resolves to its UPO in the session that accepted it, and every rejection is stored with its description and details, not only its code. The examples inassets/examples/type-check under--strict. This skill keeps its audit record in CHANGELOG.md rather than areferences/provenance.md: each release says what it fixed, added or changed and how it was verified.
Each entry is a rule that changed because the integration taught something the specification did not.
Release 1.1.0, 2026-07-21
Corrections and hardening driven by a field report from a production integration, verified against the official C#/Java clients and the live OpenAPI spec (API 2.7.0).
- Invoice encryption (send-blocking) the skill prepended the IV to the ciphertext, following a sentence in the MF docs that both official clients contradict. KSeF then decrypted 16 bytes too many and returned status
430blaming the invoice size, a false trail.encryptDocument()now returns raw ciphertext;decryptDocument()takes the IV as an argument. - Export packages parts are a binary split, so they must be concatenated before unzipping (the old loop only worked for single-part packages), and the export's IV must be persisted alongside its key to decrypt them at all.
- Duplicates (440)
status.extensionsis a string-keyed object, not a list of key/value pairs; and a duplicate's UPO lives in the original session, reachable via/sessions/{originalRef}/invoices/ksef/{ksefNumber}/upo.
- Invoice encryption (send-blocking) the skill prepended the IV to the ciphertext, following a sentence in the MF docs that both official clients contradict. KSeF then decrypted 16 bytes too many and returned status
Release 1.0.1, 2026-07-15
Correctness fixes found by re-verifying against the live OpenAPI spec.
- KSeF number validator CRC-8 was computed over 33 characters (including the separating hyphen) instead of the specified 32, so
isValidKsefNumberrejected every valid KSeF number, including the official docs' own example. - Error code extraction
ksefCodereadexceptionDetailListat the body root; it is nested underexception. The getter always returnedundefined, making the error-21470 stale-key refresh-and-retry path unreachable. It now also reads the RFC 9457errors[].codeshape, and no longer mistakes a 429 rate-limit body's HTTP status for a KSeF code. - An over-length challenge example, a checksum-invalid KSeF number example, and the claim that /permissions/attachments/status reports system availability (it reports attachment consent)
- CSR key length (RSA 2048 exactly, not a minimum) and Owner rights (excludes VatUeManage)
- KSeF number validator CRC-8 was computed over 33 characters (including the separating hyphen) instead of the specified 32, so
Non-negotiables
What are the 6 rules the module never breaks?
Every module built from this skill holds these, whoever builds it. The same list is in the skill's README and SKILL.md, so the agent reads it before it writes a line.
Upload raw ciphertext and never prepend the IV.
It is transmitted once in
encryption.initializationVector; the MF docs say otherwise, every official client contradicts them, and KSeF reports a prefixed IV as status430on the invoice size.assets/examples/crypto.tsis the reference implementation.The seller NIP must equal the authenticating context NIP.
Verify before every send, and never fall back to a shared env-var token in a multi-tenant app; either mistake files invoices under the wrong taxpayer. The check in
sending-interactive.mdruns before the session opens.No XAdES in the runtime path.
Authenticate out-of-band once, mint a KSeF token, and authenticate with pure
node:cryptofrom then on.assets/examples/auth-ksef-token.tsruns that flow with no XML library.No webhooks: submit, then poll.
State lives in your database between cron invocations, and KSeF is synced into it rather than called on a user's click, which keeps the app inside tight hourly rate limits (such as 20 metadata queries an hour, per context and IP).
Everything is server-only.
Tokens, session AES keys and invoice XML never reach a client component; credentials are encrypted at rest and never logged, echoed or embedded in code.
lib/ksef/sits behindimport 'server-only', so the build fails if a client component imports it.Persist
status.descriptionandstatus.details, not just the code.The code names the category; only the text names the fault:
430alone spans schema, hash, size and encoding faults.
Fit
When should you use it, and when not?
Use it for
- Building or debugging a KSeF integration in a Next.js, Node.js or Vercel codebase: issuing sales invoices, ingesting purchase invoices, UPO handling, QR codes, offline modes, credentials.
- Questions about KSeF API 2.0 mechanics: auth flows, sessions, encryption, rate limits, the test environment.
Not for
- Other countries' e-invoicing systems, such as ViDA, PEPPOL-only flows outside KSeF, Italian SdIInsteadThat system's own API and documentation
- Polish tax or legal adviceInsteadA tax advisor; this skill covers the API, not interpretations of the VAT Act
- KSeF 1.0 (the SessionToken/InitSigned XML API)InsteadThe Ministry's 1.0 documentation; this skill covers API 2.0 only
Build it yourself
How do I install it?
One command. The skills.sh CLI installs the skill into every skills-compatible agent it finds.
$ npx skills add timerise-ai/ksefClaude Code
Invoke with /ksef
Codex CLI
Invoke with $ksef
Gemini CLI
Invoke with /skills
Name the agents instead with -a, for example npx skills add timerise-ai/ksef -a claude-code -a codex. Or clone the repository into your agent's skills folder. Nothing in it is agent-specific.
What is inside the repository (17 entries)
SKILL.mdEntry point: when to use and when not to, the architecture and environments, eight critical facts, six hard rules, the quick start, and the reference directoryREADME.mdThis file: the human-facing front doorCHANGELOG.mdEvery release, newest first, and the record of what each one fixed, added or changed and why, which is this skill's provenanceCLAUDE.mdWhat this repository is and its editing conventions, for an agent editing the skill itselfLICENSEMITreferences/architecture-and-vercel.mdStart here for greenfield: system model, env vars, Postgres DDL, cron polling, multi-tenancy, Vercel function limits, go-live checklistreferences/crypto-and-client.mdThenode:cryptoprimitives for AES-256-CBC, RSA-OAEP key wrapping and hashes, and the typed fetch clientreferences/auth.mdChallenge flow, KSeF-token auth, access/refresh token lifecycle, the bootstrap-once XAdES stepreferences/sending-interactive.mdOnline sessions, invoice status codes,description/details/extensions, duplicates, UPO, pre-send NIP validationreferences/sending-batch.mdSesja wsadowa (batch session): the ZIP/tar.gz pipeline, part splitting, part uploadsreferences/receiving-and-sync.mdMetadata queries, export packages, high-water-mark incremental syncreferences/qr-codes-and-offline.mdKOD I / KOD II, verification links, offline24 and awaryjny modes, technical correctionsreferences/certificates-tokens-permissions.mdKSeF tokens, CSR enrollment, certificate types, the permissions modelreferences/errors-limits-and-testing.mdRate limits, error codes, troubleshooting, and the TEST-environment bootstrapassets/examples/*.tsSix runnable scripts mirroring the reference code (npx tsx <script>):crypto.ts,ksef-client.ts,auth-ksef-token.ts,send-invoice-online.ts,poll-session-status.ts,qr-codes.tsevals/The prompts an operator types after installing (prompts.md) and one file per agent eval: the skill installed into an empty Next.js app, one prompt, no help, then type-checked, built and tested.github/workflows/agent-eval.ymlRuns the agent evals on every published release through the index's reusable workflow; the same in every skill
Recent releases
- v1.2.6September 29, 2026
Documentation-only release. The skill's technical content, its endpoints, code and facts, is unchanged from 1.2.5; SKILL.md, the README, CLAUDE.md and the references are brought to the index's STANDARD.md.
- v1.2.5September 21, 2026
Wording release. The skill content is unchanged from 1.2.4.
- v1.2.4September 2, 2026
Wording release. Templates and technical content are unchanged from 1.2.3.
After installing
What do I tell my agent?
Say what you need in your own words; the skill supplies the how. These are starting points, and the ones we tested say how it went.
Send our sales invoices to KSeF API 2.0 from this Next.js app on Vercel: authenticate with a KSeF token, encrypt and send each invoice, and store the UPO and the QR code.
Pull our purchase invoices from KSeF into Postgres every night.
PostgresThe KSeF test environment returns status 430 for every invoice we send. Find the cause.
Tested
How does it do in each agent?
We install the skill into an empty Next.js app, give the agent one of the prompts above and no further help, then type-check, build and run the tests it left behind. Nothing is fixed by hand before the checks, and a failing run is published like a passing one. The procedure and every result are public, and the first prompt runs again before each release.
- Built, checks pass
Gemini CLI0.61.0
gemini-3.8-flash
Send our sales invoices to KSeF API 2.0 from this Next.js app on Vercel: authenticate with a KSeF token, encrypt and send each invoice, and store the UPO and the QR code.
Typecheck: passBuild: passTests: pass- Time
- 11 min
- Changed
- 32 files, +4,675 lines
- Stack
- Postgres
- Skill
- v1.2.6
- Run
- Sep 29, 2026
- Built, checks pass
Claude Code2.1.284
claude-opus-5-5
Send our sales invoices to KSeF API 2.0 from this Next.js app on Vercel: authenticate with a KSeF token, encrypt and send each invoice, and store the UPO and the QR code.
Typecheck: passBuild: passTests: pass- Time
- 7 min
- Changed
- 31 files, +2,808 lines
- Stack
- Postgres
- Skill
- v1.2.6
- Run
- Sep 29, 2026
Not run yet in Codex CLI.
Build it with Timerise
How long does it take, and what does it cost?
We quote this module per project. The price depends on what it has to connect to. The path to a number is short and free:
Step 1
Brief
Tell us what the module must connect to. Takes minutes, in a chat.
Step 2
Prototype in 48 hours
A clickable prototype of your system and a quote, at no cost.
Step 3
Build and handoff
One project price. Source code, documentation and IP are yours.
Two ways to get KSeF e-invoicing
Build it yourself
Install the skill. Your own agent builds the module.
- MIT licensed, no strings
- Runs in Claude Code, Codex CLI and Gemini CLI
- The same rules our engineers build by
$ npx skills add timerise-ai/ksefBuild it with Timerise
Send a brief. We build KSeF e-invoicing into a system you own.
- Clickable prototype and a quote within 48 hours, free
- One project price, no subscription, no commission
- Source code, documentation and IP handed over
Generated from the skill's own files at commit 18068ba. Every rule above links to where the repository says it. All skills