> For the complete documentation index, see [llms.txt](https://docs.younium.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.younium.com/e-invoicing-integrations/ksef.md).

# KSeF

## Overview

The KSeF (Krajowy System e-Faktur) integration submits Polish e-invoices through Maventa after Younium generates Peppol UBL with KSeF-specific rules. Younium tracks each submission in `KSeFInvoiceEntry`, synchronises status from Maventa (webhook and polling job), stores the official UPO acknowledgement, and records the KSeF invoice identifier. AutoInvoice Maventa credentials and an active vendor link are mandatory.

## Authentication

KSeF is delivered through Maventa and reuses the AutoInvoice connection, so there are no separate credentials to enter for it. AutoInvoice must be connected first.

What KSeF adds is the Polish KSeF token, which you obtain from KSeF and enter on the KSeF settings. Younium stores it and passes it to Maventa, which uses it to submit on your behalf. You can send the token to Maventa again at any time from the settings without changing anything else — useful when the token has been reissued in KSeF.

## Activation and Save settings

KSeF becomes active when it is enabled for the legal entity and a KSeF token has been entered — both are needed, and enabling it without a token leaves it inactive. The legal entity must also have KSeF turned on in Younium before any of it applies.

Saving requires AutoInvoice to be connected. The first time KSeF becomes active, Younium also links your company to Younium at Maventa if that has not happened already; if the link fails, the settings still save and the failure is recorded rather than blocking you.

Removing the KSeF settings turns KSeF off for the legal entity and leaves AutoInvoice as it was.

### Settings

| Setting               | Description                                      |
| --------------------- | ------------------------------------------------ |
| `IsEnabled`           | Whether KSeF is switched on for the legal entity |
| `KSeFToken`           | The KSeF token Younium passes to Maventa         |
| `IsIntegrationActive` | Enabled and a token entered                      |

## Legal entity validation

`ValidateLegalEntity` returns missing fields:

| Required Younium data              | Validation message      |
| ---------------------------------- | ----------------------- |
| `OrganizationNumber`               | Organization number     |
| `TaxRegistrationNumber`            | Tax registration number |
| `BankAccount` or `IBAN`            | Bank account / IBAN     |
| `BIC`                              | BIC                     |
| Address street, city, zip, country | Address fields          |

## Eligibility before submission

Before an invoice is submitted, Younium checks that:

* KSeF is turned on for the legal entity
* The KSeF settings are enabled and a token has been entered
* AutoInvoice is connected and active

Peppol XML for KSeF uses `isKSeF = true` (1-based line numbers, Polish party rules) when legal entity KSeF is enabled and KSeF integration is active.

## Post invoice workflow

**Event:** `InvoicePosted` → integration subscriber `ksef` → action `ksef-post-invoice`.

1. Skip if an entry already exists with status `Submitted` or `Processed` (avoids double submission with synchronous posting).
2. `CreatePendingEntry` for `KSeFInvoiceDirection.Sent`.
3. `EnsureKSeFAndMaventaConfigured`.
4. Send the Peppol XML to Maventa for onward submission to KSeF.
5. `MarkSubmitted` with Maventa response `id`.
6. Register `ElectronicInvoiceId` for webhook tenant resolution; set `Invoice.ElectronicInvoiceId` to invoice GUID.

On failure, `MarkFailed` with error message and integration log failure.

## KSeF entry status model

| Status      | Meaning                                            |
| ----------- | -------------------------------------------------- |
| `Pending`   | Reserved before Maventa call                       |
| `Submitted` | Maventa accepted invoice; awaiting KSeF completion |
| `Processed` | KSeF ID stored                                     |
| `Failed`    | Submission or sync error                           |

Multiple entries per invoice are allowed (repost audit trail); queries use the most recent.

## Status sync workflow

The scheduled sync polls every invoice still in **Submitted** status. A webhook from Maventa updates a single invoice by its reference, and re-delivering the same webhook has no further effect once the invoice has been processed.

| Maventa `status` | Younium action                                              |
| ---------------- | ----------------------------------------------------------- |
| `pending`        | No change                                                   |
| `error`          | `MarkFailed` with extracted error                           |
| `delivered`      | Download UPO file, parse KSeF ID, `StoreUpo`, `StoreKSeFId` |

`StoreUpo` only for direction `Sent`; does not set `Processed` until KSeF ID is stored.

Scheduled job: `KSeFStatusPollingJob` (see core job registration for schedule).

## Field mapping — tracking record

| Younium `KSeFInvoiceEntry`  | Source                              |
| --------------------------- | ----------------------------------- |
| `InvoiceId`                 | Posted invoice                      |
| `InvoiceNumber`             | Invoice number at submission        |
| `MaventaReferenceId`        | Maventa response `id`               |
| `KSeFId`                    | Parsed from UPO / Maventa files API |
| `UpoContent`, `UpoFileName` | UPO download                        |
| `Direction`                 | `Sent` for outbound                 |
| `ErrorMessage`              | Failure text                        |

## Maventa invoice details (sync)

Status is read from Maventa with the same `GET /v1/invoices/{id}` call described in the [AutoInvoice](/e-invoicing-integrations/auto-invoice.md) article.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.younium.com/e-invoicing-integrations/ksef.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
