Poland and KSeF
Preview only: Space Invoices’ KSeF integration is not yet released or production-certified. Production submissions are unavailable pending release review. This guide describes the candidate scope and behavior.
Polish entities default to PLN and pl-PL. The preview covers online FA(3) standard invoices and linked reducing corrections in PLN for active-VAT Polish B2B sellers. KSeF obligation is modeled independently of the connection switch. Configure a sandbox entity to submit to KSeF TEST; production submission is not available in this preview.
Configure access
Supply a valid Polish NIP on the entity. The API normalizes an optional PL prefix, spaces and hyphens, validates the checksum, and stores ten digits. Customer NIP validation follows the customer’s country, independently of the seller. Ordinary invoicing permits an omitted NIP; KSeF requires one.
All setup routes require entity administration access and a bearer token. Send x-entity-id on document requests.
| Method and route | Body | Result |
|---|---|---|
GET /entities/{id}/ksef | None | Setup and release-switch state |
PUT /entities/{id}/ksef/credentials | {"environment":"test","token":"<KSEF_TOKEN>"} | Stores an encrypted, write-only token |
PUT /entities/{id}/ksef | {"enabled":true} | Authenticates the token and enables submission |
PUT /entities/{id}/ksef | {"enabled":false} | Disables new submissions |
DELETE /entities/{id}/ksef/credentials | None | Removes credentials after KSeF is disabled |
The token needs the InvoiceWrite and InvoiceRead permissions. Space Invoices checks the token’s status, NIP and permissions with KSeF when you enable KSeF, and when you replace the token while KSeF is enabled or submissions are pending; if the check fails, the previous token stays in place. Enabling returns 422 if submission isn’t switched on or authentication fails.
- The token is tied to the entity’s NIP and environment. An environment mismatch returns
422. - To change the NIP, disable KSeF first and let pending submissions finish (including UPO retrieval).
- To remove the token, disable KSeF first (otherwise
422) and let pending submissions finish (otherwise409). Local preparation failures that never reserved an XML hash don’t block removal. - Generic entity updates ignore
settings.ksef; use the KSeF endpoints.
The settings response tells you:
credential_configured: a token for the current NIP and environment is stored.submission_available: Space Invoices has released KSeF submission for this environment. This is a platform switch, separate from yourenabledsetting.
KSeF is required by default, whether or not enabled is on. An entity admin can record obligation: "exempt" with an exemption_reason of at least 10 characters; this records your declaration and isn’t a legal determination. Disabling KSeF doesn’t lift the obligation or unlock pending submissions. Omitting enabled, or sending null, leaves the setting unchanged.
In the app or embed, open Settings → KSeF to store a token and enable submissions. Invoice and credit-note views show authority status, eligible retry actions and UPO download. Disabling new submissions or the operational switch preserves status and receipt recovery for existing submissions. Ordinary B2C invoicing remains available outside KSeF submission when the customer is explicitly marked with is_end_consumer: true; those invoices do not enter the KSeF submission flow.
Issue an invoice or correction
Create an invoice with POST /invoices, or finalize a draft. When KSeF is enabled, issued B2B documents are submitted automatically; drafts are not.
Only PLN standard invoices from active VAT payers, and credit notes that reduce them, are supported. Advances, offline24, foreign currency, and domestic invoices above PLN 15,000 gross are rejected before the invoice is saved. The PLN 15,000 limit is a conservative product limit, not a statement about split-payment law. While KSeF is required, disabling it doesn’t let a final Polish B2B invoice skip submission.
Provide complete seller and buyer names, addresses, country codes and tax identifiers. Use explicit tax rates. Cross-border lines require classification: "product" for goods or "service" for services and zero VAT. The mapper distinguishes intra-EU goods, exports and foreign services; it does not guess a tax treatment from an unclassified line. Domestic supported rates are 23%, 22%, 8%, 7%, 5% and explicit 0%.
Create a reducing correction through POST /credit-notes with linked_documents: ["<INVOICE_ID>"]. It must reference exactly one accepted invoice. The FA(3) correction includes the original KSeF number; stored positive credit-note amounts become negative correction amounts in XML and Polish output.
Invoice and credit-note responses expose server-managed ksef lifecycle state. Do not send it in create or update requests.
| State | Meaning |
|---|---|
reserved / processing | The submission reservation is durable; XML preparation is in progress |
dispatching | Sending started; its outcome requires reconciliation |
submitted | KSeF returned an invoice reference; acceptance is pending |
accepted | The authority invoice and its hash were verified |
rejected | KSeF rejected this submission; automatic resending is blocked |
retryable_error | Preparation failed before invoice dispatch |
Status, receipts and delivery
| Method and route | Purpose |
|---|---|
GET /invoices/{id}/ksef | Read status and reconcile pending authority results |
POST /invoices/{id}/ksef/submit | Submit or resume the existing reservation; no body |
POST /invoices/{id}/ksef/recover | Return a definitively unaccepted document to draft after an audited proof check; no body |
GET /invoices/{id}/ksef/upo | Download the verified UPO XML |
KSeF credit notes affect automatic invoice settlement and revenue reports only after verified acceptance. Pending and rejected corrections do not reduce the original invoice balance or reported revenue. Acceptance processing retries safely without applying the same credit twice. Use positive amounts for reducing corrections; increasing or mixed-direction corrections are outside this integration’s supported scope, including through /credit-notes/custom and draft finalization.
The same operations exist under /credit-notes/{id}/ksef. Status polling is rate limited. Background reconciliation uses the existing e-invoicing processing schedule. UPO may arrive after acceptance; its download returns 409 until available.
Submission is safe to repeat: repeated calls reuse the same reservation, and an interrupted submission is checked against the saved session and invoice hash, never blindly resent. A duplicate response alone doesn’t prove acceptance.
- Once reserved for KSeF, an invoice can’t be edited or voided. Correct it with a linked credit note.
- If KSeF definitively didn’t accept it, preparation failed before dispatch, or the session was cancelled and verified empty, you can recover it: the attempt is archived and the document returns to draft.
- Accepted submissions, and those whose outcome is still unknown, stay locked.
Deliver PDFs through the existing /documents/{id}/pdf endpoint after acceptance. KSeF output contains the accepted number and a verification QR code, including for foreign buyers receiving the PDF outside KSeF. Polish credit notes are titled FAKTURA KORYGUJĄCA. Ordinary Polish date, currency, character and email formatting remains available independently of KSeF.
Scope
This preview covers standard, online, outgoing PLN B2B invoices and linked reducing corrections for active VAT payers.
Not covered: foreign currency, advances, offline24 and emergency modes, domestic invoices above PLN 15,000 gross, self-billing, B2C submission to KSeF, VAT RR, attachments, special VAT procedures, and advanced corrections.
Invoices explicitly marked for end consumers can still be issued normally, outside KSeF. A PDF or a stored token alone isn’t KSeF acceptance, and this preview isn’t a certification of Polish tax compliance.
The Ministry publishes the KSeF API documentation, including TEST authentication and verification QR rules.