QuantyDocs

KSeF e-invoices

KSeF (Krajowy System e-Faktur) is Poland's national e-invoicing system. Every invoice a Polish business issues or receives goes through it: e-invoicing has been mandatory since 1 February 2026 for large taxpayers (2024 turnover above 200 million PLN), and since 1 April 2026 for everyone else.

Quanty connects to KSeF to read your invoices and turn them into rows. From there they are ordinary Quanty data: you filter them, look them up from other sheets, run AI columns over them, chart them and ask chat about them.

Only organization admins can connect KSeF. Open the KSeF card from the Integrations hub.

Quanty receives invoices, it never issues them

The integration is receive-only. Quanty reads invoices out of KSeF and writes them into your tables. It does not create, send, correct or cancel an invoice, and it does not generate the FA(3) document. That is a deliberate decision, not a gap: an invoice accepted by KSeF is a tax document with legal effect that cannot be withdrawn, only corrected. Keep issuing your invoices wherever you issue them today.

Connecting

Connecting is a three-step wizard on the KSeF page. You need an authorisation token from KSeF before you start, so read step 3 first.

1. Environment

KSeF runs three separate systems, and Quanty connects to exactly one of them:

EnvironmentWhat it reads
TestKSeF's test system. A sandbox: nothing there is a real invoice.
DemoKSeF's demo system. Also a sandbox, with its own separate data.
ProductionYour company's real invoice register.

Use test or demo to see how the sync behaves before you point anything at live data.

Production is switched off by default

The production environment is disabled at the deployment level, so nobody connects a live tax register by accident. If your workspace needs production, ask your Quanty operator to enable it for your deployment first. Test and demo are always available.

2. NIP

The NIP is the ten-digit tax identifier of the taxpayer whose invoices you want to read. Quanty checks the NIP checksum before it sends anything to KSeF, so a typo is caught immediately rather than turning into a failed connection.

3. Authorisation token

You generate the token yourself, in the KSeF taxpayer application:

EnvironmentWhere you generate the token
Productionap.ksef.mf.gov.pl/web/
Testap-test.ksef.mf.gov.pl/web/
Demoap-demo.ksef.mf.gov.pl/web/

Give the token a read permission and nothing else. Reading invoices is all Quanty needs, and a token limited to reading cannot be used to issue anything, whatever happens to it.

Quanty verifies the token against KSeF before it stores it. A token KSeF rejects is never saved, so a connection that exists is a connection that works. Once stored, the token is encrypted at rest and never shown again: only its last four characters appear anywhere in the interface.

What you can change later

Environment and NIP are fixed once the connection exists. Changing either would point a running sync at a different tax system or at a different company, so Quanty asks you to create a new connection instead of editing the one you have.

The token can be rotated in place. Paste a new one when the old one expires or you want it replaced; Quanty verifies it the same way and swaps it, leaving everything already synced untouched.

Receiving invoices

Registers and destination tables

KSeF keeps two registers: purchases (invoices issued to you) and sales (invoices you issued). Configure one, the other, or both. Each is set up separately, so purchases and sales can go to different tables.

For each register you pick the table the invoices land in, or choose Create a new table and Quanty makes one for you. There is nothing to prepare either way: Quanty provisions the columns itself on the first sync.

What lands in a row

Each invoice becomes one row, and each invoice lands once. The KSeF number is the key: an invoice already in the table is never added again, however many times a sync sees it.

ColumnWhat it holds
KSeF numberThe number KSeF assigned to the invoice. Unique, and the deduplication key.
Invoice numberThe number from the invoice itself.
Issue dateThe date on the invoice.
Seller and Seller NIPOn the purchases register: who invoiced you.
Buyer and Buyer NIPOn the sales register: who you invoiced.
Net, VAT, GrossThe amounts.
CurrencyThe invoice currency.
Document typeThe KSeF document type.
Assigned in KSeFThe date KSeF gave the invoice its number.
StatusYours to use. See below.

The Status column

Status is Quanty's column, not KSeF's. The sync writes it once, when it creates the row, and never touches it again.

That makes it safe to use as your own workflow column. Move an invoice to whatever state your process uses, by hand, from a Kanban board or from an automation, and no later sync will overwrite it.

How often Quanty checks

The sync interval is set per connection. The minimum is 30 minutes and the default is 60.

The limit is KSeF's, not Quanty's: a taxpayer may run only 20 invoice-metadata queries per hour, and one sync uses several of them. A tighter interval would spend that budget without bringing invoices in any sooner.

Sync now runs a sync immediately when you do not want to wait for the next one.

The first sync and older invoices

The first sync looks 90 days back by default. Set an earlier start date if you need more history.

Quanty walks the history in chunks and remembers where it stopped, so a long backfill spreads itself over several runs instead of failing in one. If KSeF throttles the requests, the run ends cleanly and the next one continues from the same place. A run that ends that way is not a failure; nothing is lost and nothing is duplicated.

Working with the rows

Once the invoices are rows, everything ordinary applies: filter and group them, move them across a Kanban board by status, put them on a calendar by issue date, compute with formulas, read them with AI columns, chart them on a dashboard and ask chat about them.

The KSeF invoice data column

KSeF invoice data is a column type that answers from the invoices Quanty has already synced. There is no model behind it and no prompt to write: it reads your own copy of the data, so it answers instantly and costs nothing.

Configure it with:

  • How to match — by NIP (the counterparty), by KSeF number, or by invoice number.
  • Which column holds the key — the column in this table that the NIP or the number is read from. On a table the sync itself fills you can leave this empty, and each row answers about its own invoice.
  • Which register — purchases, sales or both.
  • Period — all time, this month, this year, or the last 12 months.
  • What to return — the gross, net or VAT total; the number of invoices; the date, invoice number or KSeF number of the last invoice. When the match identifies a single invoice, that invoice's own fields can be returned instead.

Example: what we buy from each supplier

You keep a table of suppliers with a NIP column.

  1. Add a column and pick KSeF invoice data as its type.
  2. Match by NIP, and point it at your NIP column.
  3. Register: purchases.
  4. Period: this year.
  5. Return: gross total.

Every supplier row now shows how much you have bought from that supplier this year. Add a second lookup returning the invoice count and a third returning the date of the last invoice, and the table answers who you buy from, how much and when they last invoiced you, without anyone opening KSeF.

Cost and refreshing

The column recomputes when the sheet runs, like any other computed column. Because it reads Quanty's copy of the invoices instead of calling KSeF, refreshing it costs no credits and does not spend your hourly KSeF query budget.

AI columns and chat

An AI column can look invoices up while it reasons, so a prompt about a counterparty is answered from what KSeF actually holds. The chat panel answers the same kind of question directly, in your own words: ile wydaliśmy u tego dostawcy w sierpniu.

Two things are true of both:

  • They read the synced invoice record, not the cells in your grid. The answer is the tax system's account of the invoice, not whatever somebody typed over a cell.
  • Totals cover every matching invoice, not only the ones currently on screen. Filtering a view does not change the number they return.

The KSeF invoice received trigger

Triggers & automations gains a trigger type, KSeF invoice received. It fires when a sync brings in a new invoice.

Filters

Narrow it so it fires only for the invoices you care about:

  • Register — purchases, sales or both.
  • Seller NIP and Buyer NIP.
  • Document type.
  • Currency.
  • Gross range — a lower bound, an upper bound, or both.

What it acts on

The trigger acts on the row the sync has just created, so it cannot produce a duplicate of that row, and one invoice fires it once. From there the ordinary actions apply: run the AI columns on the new row, notify people, update the record, send an email.

Invoice placeholders

Action templates can quote the invoice that fired the trigger. Fourteen placeholders are available, one per field of the invoice that fired the trigger:

{{invoice.number}}, {{invoice.ksef_number}}, {{invoice.direction}}, {{invoice.type}}, {{invoice.seller}}, {{invoice.seller_nip}}, {{invoice.buyer}}, {{invoice.buyer_nip}}, {{invoice.net}}, {{invoice.vat}}, {{invoice.gross}}, {{invoice.currency}}, {{invoice.issue_date}} and {{invoice.nip}} (your own NIP).

Build it on the right table

The automation has to live on the table that register writes into. A trigger on any other table never sees the invoice rows, and the builder warns you when the table you picked is not the destination of a KSeF register.

Security

  • The authorisation token is encrypted at rest and is never returned by the API. Only its last four characters are ever displayed.
  • Only organization admins can connect KSeF, rotate a token or disconnect.
  • Every invoice is scoped to the workspace that synced it.
  • Disconnecting wipes the stored credentials.
  • Quanty reads invoices and nothing else. It cannot issue, correct or cancel one.