Guide API KSeF 2.0
Référence technique complète pour l'intégration avec l'API KSeF du Ministère des Finances polonais
Avertissement
Ce guide est fourni à titre informatif et se base sur la documentation API KSeF 2.0 et nos tests réels sur l'environnement TEST. Les spécifications peuvent évoluer. Consultez toujours la documentation officielle du Ministère des Finances polonais pour les informations les plus récentes.
1. Environnements
Le KSeF propose trois environnements distincts. Utilisez toujours TEST ou DEMO pour le développement.
| Environnement | URL | Usage |
|---|---|---|
| TEST | https://api-test.ksef.mf.gov.pl/v2 | Tests libres, NIP fictifs |
| DEMO | https://api-demo.ksef.mf.gov.pl/v2 | Démonstration |
| PROD | https://api.ksef.mf.gov.pl/v2 | Production (obligatoire depuis le 01/02/2026) |
2. Authentification
Chaque session API nécessite une authentification par token. Le flux complet utilise un chiffrement RSA-OAEP du token avec la clé publique du KSeF.
Flux complet (token API)
1. GET /security/public-key-certificates → RSA keys
2. POST /auth/challenge → challenge + timestampMs
3. RSA-OAEP(token|timestampMs) → encrypt with "KsefTokenEncryption" key
4. POST /auth/ksef-token → challenge + encryptedToken
→ authenticationToken + referenceNumber (HTTP 202)
5. GET /auth/{referenceNumber} → poll until code=200
6. POST /auth/token/redeem → exchange → accessTokenHeaders requis pour les appels authentifiés
Authorization: Bearer {accessToken}
Accept: application/json
Content-Type: application/jsonClés publiques
GET /security/public-key-certificates renvoie 2 certificats :
| Usage | Utilisation |
|---|---|
KsefTokenEncryption | Chiffrement du token lors de l'authentification |
SymmetricKeyEncryption | Chiffrement de la clé AES de session |
Pas de champ fingerprint dans la réponse (contrairement à la documentation).
3. Session Online (interactive)
Pour envoyer des factures sans pièce jointe, une par une.
1. POST /sessions/online → open session
2. POST /sessions/online/{ref}/invoices → send invoice
3. GET /sessions/{ref}/invoices/{invoiceRef} → check status
4. POST /sessions/online/{ref}/close → close sessionOuverture de session
{
"formCode": {"systemCode": "FA (3)", "schemaVersion": "1-0E", "value": "FA"},
"encryption": {
"encryptedSymmetricKey": "RSA-OAEP(aes_key, cert_SymmetricKeyEncryption)",
"initializationVector": "base64(iv_16_bytes)"
}
}Le client génère la clé AES-256 et l'IV, chiffre la clé avec RSA, envoie les deux.
Envoi d'une facture
{
"invoiceHash": "base64(SHA256(xml_raw))",
"invoiceSize": 2048,
"encryptedInvoiceHash": "base64(SHA256(xml_encrypted))",
"encryptedInvoiceSize": 2064,
"encryptedInvoiceContent": "base64(AES-256-CBC(xml_raw))"
}Chiffrement AES-256-CBC avec PKCS#7 padding. Même clé/IV que la session.
4. Session Batch (wsadowa)
Pour envoyer des factures avec ou sans pièces jointes, en lot (ZIP).
1. Create ZIP containing XML invoices (faktura_1.xml, faktura_2.xml, ...)
2. Encrypt ZIP with AES-256-CBC + PKCS#7 (NO IV prepend)
3. POST /sessions/batch → open session, receive upload URL
4. PUT {uploadUrl} → upload encrypted ZIP (raw bytes)
5. POST /sessions/batch/{ref}/close → close and start processing
6. GET /sessions/{ref} → poll session status
7. GET /sessions/{ref}/invoices → accepted invoices
8. GET /sessions/{ref}/invoices/failed → rejected invoicesOuverture session batch
{
"formCode": {"systemCode": "FA (3)", "schemaVersion": "1-0E", "value": "FA"},
"batchFile": {
"fileSize": 1078,
"fileHash": "base64(SHA256(zip_raw))",
"fileParts": [{
"ordinalNumber": 1,
"fileSize": 1088,
"fileHash": "base64(SHA256(zip_encrypted))"
}]
},
"encryption": {
"encryptedSymmetricKey": "...",
"initializationVector": "..."
}
}| Champ | Valeur |
|---|---|
batchFile.fileSize | Taille du ZIP avant chiffrement |
batchFile.fileHash | SHA256 du ZIP avant chiffrement |
fileParts[].fileSize | Taille du ZIP après chiffrement |
fileParts[].fileHash | SHA256 du ZIP après chiffrement |
Upload : la réponse contient partUploadRequests avec URL, méthode (PUT) et headers (x-ms-blob-type: BlockBlob). Envoyer les bytes chiffrés bruts, sans Authorization header.
Chaque facture est traitée indépendamment. Une erreur sur une facture ne bloque PAS les autres.
Contrairement à une idée reçue, le traitement batch n'est pas atomique : les factures valides reçoivent leur ksefNumber même si d'autres factures du même lot sont rejetées.
Retours par facture
Après fermeture de la session batch, chaque facture est traitée indépendamment. Consultez les résultats via deux endpoints distincts.
GET /sessions/{ref}/invoices → accepted invoices (with ksefNumber)
GET /sessions/{ref}/invoices/failed → rejected invoices (with processingCode + error)Le traitement est parallèle : les factures acceptées et rejetées peuvent apparaître dans un ordre différent de celui du ZIP.
5. Codes de traitement
Les réponses API utilisent des codes de traitement (processingCode) pour indiquer l'état de la requête. Un même code peut avoir des significations légèrement différentes selon l'endpoint (auth, session, facture, export).
Progression (100-299)
| Code | Signification |
|---|---|
| 100 | Processus enregistré / accepté pour traitement |
| 150 | En cours de traitement (remplace l'ancien code 300 depuis RC3) |
| 170 | Traitement terminé |
| 200 | Succès → ksefNumber disponible, session traitée, export terminé |
| 210 | Export expiré, plus disponible au téléchargement |
Erreurs (400-550)
| Code | Signification |
|---|---|
| 400 | Échec opération, demande rejetée |
| 405 | Erreur vérification paczka (sanity check) / erreur session |
| 410 | Identifiants incohérents, portée permissions invalide |
| 415 | Permissions manquantes, erreur déchiffrement clé, PJ non autorisées |
| 420 | Filtres trop larges, limite factures dépassée, permission refusée |
| 425 | Token invalidé / hash fichier invalide |
| 429 | Rate limit dépassé (~100/s, ~300/min, ~1200/h) |
| 430 | Erreur décompression, erreur vérification facture, rôle manquant |
| 435 | Erreur déchiffrement fichier (chiffrement incorrect) |
| 440 | Session annulée (timeout upload), doublon facture, opération interdite |
| 441 | Erreur vérification sous-processus traitement facture |
| 445 | Erreur finalisation, aucune facture valide trouvée |
| 450 | Token invalide, erreur structure facture, XML invalide |
| 460 | Échec certificat (invalide, chaîne non fiable, révoqué) |
| 470 | Tentative d'utilisation des méthodes d'autorisation d'une personne décédée |
| 480 | Auth bloquée : suspicion incident sécurité (contacter MF via formulaire) |
| 500 | Erreur serveur inconnue |
| 550 | Opération annulée par le système (atomique, aucun traitement partiel). Réessayer. |
Source : Issue #526, OpenAPI spec, api-changelog.md
6. Limites
| Paramètre | Valeur |
|---|---|
| Taille max facture sans PJ | 1 MB |
| Taille max facture avec PJ | 3 MB (configurable jusqu'à 10 MB) |
| Factures max par session batch | 10 000 000 |
| Taille max ZIP | 5 GB |
| Parts max par ZIP | 50 (100 MB chacune) |
| Timeout session batch non fermée | 12h → annulation auto (code 440) |
Vérifiable via GET /limits/context.
7. Pièces jointes (Zalacznik)
Prérequis
- 1.Activation :
POST /testdata/attachmentavec {"nip": "..."} (env TEST). En PROD : déclaration via e-Urząd Skarbowy. - 2.Session batch obligatoire : le mode online rejette les PJ (code 415).
Vérification
GET /permissions/attachments/status (authenticated)
{"isAttachmentAllowed": true}
// or with revocation date:
{"isAttachmentAllowed": true, "revokedDate": "2026-12-31T23:59:59+00:00"}Structure XML
'<Zalacznik>' est un enfant direct de '<Faktura>' (pas de '<Fa>'), avec structure structurée :
<Faktura xmlns="http://crd.gov.pl/wzor/2025/06/25/13775/">
<Naglowek>...</Naglowek>
<Podmiot1>...</Podmiot1>
<Podmiot2>...</Podmiot2>
<Fa>...</Fa>
<Zalacznik>
<BlokDanych>
<MetaDane>
<ZKlucz>Key</ZKlucz>
<ZWartosc>Value</ZWartosc>
</MetaDane>
<Tabela>
<Opis>Table description</Opis>
<TNaglowek>
<Kol Typ="txt"><NKom>Column 1</NKom></Kol>
<Kol Typ="int"><NKom>Column 2</NKom></Kol>
</TNaglowek>
<Wiersz>
<WKom>Value 1</WKom>
<WKom>42</WKom>
</Wiersz>
</Tabela>
</BlokDanych>
</Zalacznik>
</Faktura>Types de colonnes : txt, int, dec, date.
Codes erreur PJ
| Code | Mode | Message |
|---|---|---|
| 415 | Online | "Wysylanie faktury z zalacznikiem w trybie interaktywnym nie jest dozwolone" |
| 410 | Batch | "Sprzedawca {NIP} nie posiada zgody do wysylania faktur z zalacznikami" |
8. Endpoints testdata (env TEST)
Pas besoin d'authentification. Ces endpoints permettent de configurer l'environnement de test.
| Endpoint | Méthode | Statut | Notes |
|---|---|---|---|
/testdata/subject | POST | OK | {"subjectNip": "...", "description": "..."} |
/testdata/person | POST | OK | {"nip": "...", "pesel": "...", "description": "..."} |
/testdata/attachment | POST | OK | {"nip": "..."} — active les pièces jointes |
/testdata/attachment/revoke | POST | OK | {"nip": "..."} — révocation non immédiate |
/testdata/permissions | POST | 500 | Cassé depuis le lancement KSeF 2.0 |
9. Endpoints d'information
Endpoints authentifiés pour consulter l'état de votre compte et de vos factures.
| Endpoint | Description |
|---|---|
/permissions/attachments/status | Statut autorisation pièces jointes |
/limits/context | Limites de session (taille max, etc.) |
/rate-limits | Rate limits actuels |
/auth/sessions | Sessions actives |
/invoices/query/metadata | Recherche de factures (filtre hasAttachment) |
/invoices/ksef/{ksefNumber} | Télécharger une facture par numéro KSeF |
10. Problèmes connus
Points d'attention lors de l'intégration avec l'API KSeF, basés sur nos tests réels :
| Problème | Source | Détails |
|---|---|---|
| POST /testdata/permissions renvoie 500 | #296 | Cassé depuis le lancement KSeF 2.0. Même avec le format exact du schéma OpenAPI, le serveur renvoie 500 Internal Server Error. |
| Révocation PJ non immédiate | Tests 04/02/2026 | Après appel de /testdata/attachment/revoke, isAttachmentAllowed reste true avec un revokedDate futur. |
| Serveur TEST lent (code 150 prolongé) | #408, #278 | Post-lancement, le traitement peut rester en code 150 ("En cours de traitement") plus longtemps que prévu. |
| PJ rejetée en mode online (415) | #674 | Pas un bug : les PJ nécessitent obligatoirement une session batch. Le mode online renvoie 415. |
Liens utiles
Besoin d'aide pour l'intégration KSeF ?
Nous vous accompagnons dans l'intégration API : authentification, envoi de factures, gestion des erreurs et mise en production.
Avertissement
Ce guide est fourni à titre informatif et se base sur la documentation API KSeF 2.0 et nos tests réels sur l'environnement TEST. Les spécifications peuvent évoluer. Consultez toujours la documentation officielle du Ministère des Finances polonais pour les informations les plus récentes.