KSeF API

KSeF API: send e-invoices to Poland's KSeF with one POST

The official KSeF 2.0 API asks you to handle a challenge-based login, RSA-OAEP encryption, interactive sessions, status polling and UPO retrieval. Notaly wraps all of it: you send JSON, we generate FA(3) XML, submit it to KSeF and notify you when it is accepted.

Updated 6 min read

What the KSeF API is

KSeF (Krajowy System e-Faktur) is Poland's national e-invoicing system, run by the Ministry of Finance. Every structured invoice is an FA(3) XML document that has to be submitted to KSeF, where it receives a unique KSeF number and an official receipt, the UPO.

The official KSeF 2.0 API (https://api.ksef.mf.gov.pl/v2) is a low-level REST interface. Integrating it directly means building all of this yourself:

  • a challenge-based login with a KSeF token or certificate, with the token encrypted using the Ministry's RSA-OAEP public key;
  • access and refresh tokens, and per-session AES keys to encrypt each invoice;
  • generating FA(3) XML that passes the official XSD, down to totals and VAT annotations;
  • polling the session and invoice status until KSeF decides, then fetching the UPO;
  • separate hosts, keys and tokens for the TEST, DEMO and PRODUCTION environments.

One POST instead of a KSeF integration

Notaly is an e-invoicing API for Poland that does that work for you. You send the invoice as JSON; Notaly generates FA(3) XML, validates it, submits it to KSeF, follows the status and tells you the result.

POST/invoices201 Created
curl -X POST https://api.getnotaly.com/invoices \
  -H "Authorization: Bearer $NOTALY_API_KEY" \
  -H "Idempotency-Key: FV-2026-10-001" \
  -H "Content-Type: application/json" \
  -d '{
    "number": "FV/2026/10/001",
    "issueDate": "2026-10-12",
    "currency": "PLN",
    "seller": { "nip": "2745013933", "name": "Example Sp. z o.o.",
                "address": { "line1": "ul. Testowa 1, 00-001 Warszawa", "country": "PL" } },
    "buyer":  { "nip": "1234563218", "name": "Test Customer S.A.",
                "address": { "line1": "ul. Probna 2, 30-001 Kraków", "country": "PL" } },
    "items": [ { "name": "SaaS subscription", "quantity": 1, "unitNetPrice": 1000, "vatRate": 23 } ]
  }'

The response is the invoice object with "status": "submitted" and a KSeF reference number. When KSeF decides, you receive a signed invoice.accepted webhook with the KSeF number, the UPO and a PDF link. Full details are in the API reference.

Sandbox: on KSeF TEST the seller NIP must be 2745013933, the NIP of Notaly's test certificate. Any other seller is rejected with 422 seller_nip_not_authorized before reaching KSeF, so it does not use up a free invoice.

Invoice lifecycle

An invoice moves through four API statuses. KSeF also has an internal processing phase, but the API keeps the invoice as submitted until KSeF decides.

StatusMeaningWhat you get
draftFA(3) XML generated and stored, not sent yet (for example, KSeF was unavailable).id, XML
submittedSent to KSeF; stays here while KSeF processes it.KSeF reference number
acceptedAccepted by KSeF.KSeF number, UPO, PDF with QR code
rejectedRejected by KSeF.Stable error code, e.g. ksef_rejected:<code>

KSeF environments

KSeF has three separate environments. Tokens, keys and invoices from one never work in another.

EnvironmentAPI hostCredentialsLegal effect
TESTapi-test.ksef.mf.gov.plFictitious dataNo
DEMOapi-demo.ksef.mf.gov.plReal NIP and tokenNo
PRODUCTIONapi.ksef.mf.gov.plReal NIP and tokenYes

Today the whole Notaly flow runs on KSeF TEST. Production follows after tax and legal validation; paid plans then use your own company's KSeF token.

Who has to use KSeF

KSeF became mandatory for B2B invoices in Poland in 2026: from 1 February 2026 for companies whose 2024 sales exceeded PLN 200 million, and from 1 April 2026 for the other VAT taxpayers. The smallest businesses got a later start date. If you build invoicing, ERP, e-commerce or billing software that serves Polish companies, your product needs to issue invoices through KSeF.

Notaly issues and tracks e-invoices. It is not an accounting service and does not calculate taxes.

Pricing

PlanPriceInvoices
SandboxFree3 test invoices on KSeF TEST
Starter€49/monthUp to 200 per month
Scale€199/monthUp to 1,000 per month

Create a sandbox account on the home page. Your API key appears in seconds, and no credit card is needed.

Frequently asked questions

What is the KSeF API?

It is the Ministry of Finance REST API (KSeF 2.0, /v2) used to authenticate, send structured FA(3) invoices to KSeF and read their status and UPO. Notaly is a developer-friendly layer on top of it: one POST /invoices with JSON instead of sessions, encryption and polling.

Do I need my own KSeF token to try Notaly?

No. Sandbox accounts submit to KSeF TEST with Notaly's test credentials (seller NIP 2745013933) and include 3 free test invoices. You connect your own company's KSeF token when you move to a paid plan.

Which KSeF environments does Notaly support?

Today the full flow runs on KSeF TEST. The KSeF client is already environment-aware (TEST, DEMO, PRODUCTION); production follows after tax and legal validation.

How do I know when KSeF accepts an invoice?

Notaly polls KSeF for you and sends a signed webhook (invoice.accepted or invoice.rejected) with the KSeF number, UPO and a PDF link. You can also call GET /invoices/{id} at any time.

How much does the KSeF API cost?

The sandbox is free. Starter is €49/month for up to 200 invoices and Scale is €199/month for up to 1,000 invoices.

Issue your first KSeF test invoice today

Create a sandbox account: API key in seconds, 3 free test invoices on KSeF TEST, no credit card.