Issuing a structured invoice using the Open API of the National e-Invoice System (KSeF)

The process of issuing an e-Invoice using the KSeF API is not trivial at all, so we have prepared the instructions below so that anyone who is not afraid can try their hand at this "competition". Anyway, there's no point in extending the introduction - see for yourself:

1. Authorization challenge

To start communication with the KSeF API, we first need to call AutrhorisationChallenge , i.e. the so-called authorization challenge based on which we will be able to establish a session. So we invoke:

POST /online/Session/AuthorisationChallenge

Where we enter the time in timestamp format (e.g.: "timestamp": "2023-10-10T13:00:00Z") and identifier type ("identifierType": "onip") and its value ("identifier": "<nip wystawcy faktury>")

The timestamp and the value of the authorization challenge itself will be returned

Faktury KSeF API - wyzwanie autoryzacyjne

2. Session signed

Then we invoke the establishment of a signed session:

POST /online/Sesision/InitSigned

InitSessionSignedRequest – contains an optional section Encryption – each invoice sent as part of the created interactive session will be encrypted with the symmetric key indicated in the session Encryption.

We add:

  1. the context in which we work, i.e. attribute <Context><Identifier> – by entering the invoice issuer's Tax Identification Number
  2. authorization challenge, i.e. attribute <Context><Challenge> – we enter
  3. timestamp, i.e. attribute <Context><Timestamp> – we enter – Attention! the tag is valid for 5 minutes
  4. The authentication request prepared in this way should be signed using a qualified signature or an electronic seal that contains a number PESEL number given in context
  5. Once the signature is completed, an element is added to the request <ds:Signature> containing, among others, signature (value from the hash function) and an X.509 certificate which is used to verify the correctness of the XAdES signature.
  6. We send the authentication request prepared in this way using the method POST /online/Sesision/InitSigned
  7. No authorization, because we cannot link the PESEL number to this specific company (company's Tax Identification Number) from the context.
  8. The authentication request must be signed with a signature or electronic seal with the NIP number - so that it is possible to link (confirm) the provided NIP number in the context.
  9. If we use the signature/stamp with the NIP, then in response we will get:
    1. Session reference number referenceNumber"- a very important attribute is used to check the session status and download UPO.
    2. Session token – attribute sessionToken : { "token", "context" …. }

Faktury KSeF API - nawiązanie sesji

Attention! Having a session token - each subsequent query should be authorized with this token

3. Granting permission to send requests to KSeF

Granting authorizations (i.e. to whom and what we grant) for a specific PESEL number, i.e. to a person who within the company will be able to, for example, issue and read invoices:

Faktury KSeF API - żądanie nadania uprawnień

POST /online/Credentials/Grant

Faktury KSeF API - wywołanie nawiązania sesji

Faktury KSeF API - odpowiedź nawiązania sesji

The process of granting permissions is asynchronous and may take a while. But using the value of the returned attribute elementReferenceNumber we can find out what the status is - in this case - of granting permissions.

3a. Checking the status of granting permissions

GET /online/Credentials/Status/{CredentialsElementReferenceNumber}

Faktury KSeF API - sprawdzenie statusu nadania uprawnień

  • Status Proces został zarejestrowany (processingCode:100) means that the process of granting permissions has just started.
  • Status Proces uprawnień zakończony (processingCode:200) means that permissions have been granted

4. Authentication request

Now, having been granted PESEL permissions, we can once again send a signed authentication request with a qualified signature (with PESEL):

POST /online/Sesision/InitSigned

In response we should receive:

Faktury KSeF API - wysłanie podpisanego żądania uwierzytelniającego

He is important session token (token), which allows you to perform operations such as issuing and receiving invoices. Of course, there is also a completely different session (different value for referenceNumber).

5. Generating an authorization token

Below are examples of requests that should be sent to the method GenerateToken.

POST /online/Credentials/GenerateToken

Faktury KSeF API - przykład żądania wygenerowania tokenu autoryzacyjnego

Call and response:

Faktury KSeF API - wysłanie żądania wygenerowania tokenu autoryzacyjnego

Attention! Authorization token (authorisationToken) is returned and available for download only once after calling the method GenerateToken, later it is no longer obtainable.

This authorization token can now be entered in the application.

Due to processingCode:100 we need to check when the token generation process will end…. And only then (when it will be processingCode:200) the token will be ready to use.

5a. Checking the token generation status

In order to check the token generation status, we need to send the attribute value elementReferenceNumber from the answer obtained in step 5 send to the method address:

GET /online/Credentials/Status/{CredentialsElementReferenceNumber}

6. Establishing a session enabling sending e-Invoices

If we have an authorization token, now we need to establish a session with it in order to perform activities such as sending or receiving invoices.

  1. We generate an authorization challenge in the same context: POST /online/Session/AuthorisationChallenge
  2. We are preparing the request InitSessionTokenRequest, where we fill in the attributes: timestamp (from authorization challenge), challenge (also from an authorization challenge), identifier (consistent with the context) and token – according to the documentation it is Base64():

KSeF - kodowanie żądania

Attention! We no longer have to sign such a prepared request - this is the difference between establishing a session using a signature and a session using an authorization token.

KSeF API - odpowiedź zawierająca token sesyjny

In response we get session token: in the attribute sessionToken > token

Attention! With this token we can only issue/receive invoices!!!

7. Sending the e-Invoice to KSeF

PUT /online/Invoice/Send

Value in the invoice attribute <Podmiot1><DaneIdentyfikacyjne><NIP> must be the same as the context value declared in the authorization challenge. The exception is, for example, self-invoicing, in which case a different NIP may appear in this field, but you must have the authorization to self-invoice (and the recipient's data must be consistent with the NIP declared in the authorization challenge).

Request example:

Faktury KSeF API - przykład żądania wystawienia e-Faktury

  1. We authorize the session using a session token
  2. If there is an active session, we invoke it PUT /online/Invoice/Send and send the request containing: invoice abbreviation (hashSHA), size (fileSize) and the invoice itself (invoiceBody)
  3. In response, we receive information that the process of collecting the sent invoice has started:

Faktury KSeF API - wysłanie żądanie wystawienia efaktury ustrukturyzowanej i odbiór odpowiedzi

Attention! Attribute referenceNumber, i.e. the session reference number should be put aside because after it we will be able to check and download the UPO.

7a. Checking the status of receipt of the invoice we sent by KSeF

GET /online/Credentials/Status/{CredentialsElementReferenceNumber}

KSeF API - sprawdzenie statusu otrzymania wysłanej efaktury przez Krajowy System e-Faktur

If the invoice has been accepted (status 200), this attribute is important ksefReferenceNumber, which uniquely identifies the invoice. Attribute acquisitionTimestamp will specify the date and time when exactly the invoice was accepted into the KSeF system.

Yes, that's it and we can be happy about issuing the first e-invoice in KSeF.

This entry was based on Webinar conducted on November 25, 2022. by representatives of the Ministry of Finance.

Update 01/05/2024 – Due to the availability of a dedicated interface KSEF REST API We encourage you to read it on nip24.pl documentation.

en_GBEnglish (UK)