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?
A KSeF integration has one hard requirement: an invoice that leaves your app is a legally binding tax document, filed under a taxpayer's NIP, and nothing in the API checks that the taxpayer is yours. This skill was written by the engineer who has shipped this integration, starting from the Ministry of Finance's own API 2.0 specification and corrected against what integrating it taught us. The references are written so that requirement holds by construction: 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; CHANGELOG.md is the record.
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
Verified against
Distilled from the official Ministry of Finance integrator documentation (Polish): https://github.com/CIRFMF/ksef-api, and the per-environment Swagger at {base}/docs/v2. Official SDKs: CIRFMF/ksef-client-csharp, CIRFMF/ksef-client-java. Facts verified against the API 2.0 docs as of mid-2026; statutory dates, rate limits and platform numbers change — confirm against the live docs, GET /rate-limits, and current Vercel documentation.
Part of the Timerise Skills index, which lists the sibling skills.
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 invoice 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.
No XAdES in the runtime path.
Authenticate out-of-band once, mint a KSeF token, and authenticate with pure
node:cryptofrom then on.No webhooks: submit, then poll.
State lives in your database between cron invocations; sync KSeF into it rather than proxying user clicks into tight hourly rate limits (e.g. 20 metadata queries/hour, per context and IP).
Everything is server-only.
Tokens, session AES keys and invoice XML never reach a client component, and credentials are encrypted at rest.
Persist
status.descriptionandstatus.details, not just the code.430is an umbrella over schema, hash, size and encoding faults; only the text says which. And FA(3) is the only FA schema DEMO and PRD accept, while FA(2) works on TEST only.
Fit
When should you use it, and when not?
Use it for
- Building or debugging any KSeF integration in a Next.js / Node.js / 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, 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 (12 entries)
SKILL.mdEntry point: critical facts, environments, quick start, and the reference directoryreferences/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.tsCHANGELOG.mdThe release history and the record of what each release changed and why, which is this skill's provenance
Recent releases
- 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.
- v1.2.3September 2, 2026
Documentation-only release. The skill itself, SKILL.md and references/, is unchanged from 1.2.2. The repository history starts at this release.
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.
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.
PostgresPull our purchase invoices from KSeF into Postgres every night.
PostgresThe KSeF test environment returns status 430 for every invoice we send. Find the cause.
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 f3e3be2. Every rule above links to where the repository says it. All skills