Limity API KSeF w 2026 roku: bezpieczne ponawianie żądań

Poznaj aktualne limity API KSeF, działanie okien kroczących i sposób ponawiania żądań po błędzie 429 bez powielania wysyłki faktur.

Ernest Bursa

Ernest Bursa

Founder · · 13 min czytania
Senior integration engineer monitoring three KSeF API quota windows and a paused invoice retry queue from a Warsaw operations desk

To tlumaczenie moze byc nieaktualne. Zobacz po angielsku

Limity API KSeF obowiązują jednocześnie w kroczących oknach sekundowym, minutowym i godzinowym, zazwyczaj osobno dla każdej pary (kontekst, IP). Gdy KSeF zwraca HTTP 429, odczekaj czas podany przez serwer w nagłówku Retry-After, wstrzymaj wszystkie procesy robocze korzystające z tego samego limitu i uzgodnij zapisane identyfikatory sesji lub faktury. Dopiero potem ponów wysyłkę, której wynik pozostaje niepewny.

To rozróżnienie jest ważne. Odpowiedź 429 mówi, kiedy spróbować ponownie. Po utracie połączenia tuż po wysłaniu faktury nie wiadomo natomiast, czy KSeF ją przyjął. Traktowanie obu sytuacji jak zwykłego ponowienia może prowadzić do wielokrotnego wysłania tej samej faktury, dłuższych blokad i coraz mniej stabilnej kolejki.

To techniczny przewodnik dla osób utrzymujących integrację, a nie porada podatkowa ani prawna. Poniższe wartości pochodzą z obowiązujących specyfikacji KSeF, sprawdzonych 28 sierpnia 2026 roku.

Jakie limity API KSeF obowiązują w środowisku produkcyjnym?

KSeF przypisuje grupom operacji API odrębne limity sekundowe, minutowe i godzinowe. Wszystkie trzy obowiązują jednocześnie, więc limit godzinowy może zatrzymać klienta, który ani razu nie przekroczył limitu sekundowego.

W dniu weryfikacji środowiska produkcyjne i DEMO działały na API 2.6.1. Środowisko TEST korzystało z wersji 2.7.1, ale wspólne grupy punktów końcowych miały takie same wartości domyślne. Obowiązujący kontrakt OpenAPI środowiska produkcyjnego podawał następujące limity:

Grupa limitów Przykładowa operacja żąd./s żąd./min żąd./godz.
onlineSession Otwarcie lub zamknięcie sesji interaktywnej 10 30 120
batchSession Otwarcie lub zamknięcie sesji wsadowej 10 20 60
invoiceSend Wysłanie faktury w sesji interaktywnej 10 30 180
invoiceStatus Pobranie statusu jednej faktury 30 120 1 200
sessionList Wyświetlenie listy sesji 5 10 60
sessionInvoiceList Wyświetlenie faktur w sesji lub faktur odrzuconych 10 20 200
sessionMisc Pozostałe operacje na sesjach, fakturach i UPO 10 120 1 200
invoiceMetadata Wyszukiwanie metadanych faktur 8 16 20
invoiceExport Rozpoczęcie eksportu faktur 8 16 20
invoiceExportStatus Sprawdzenie statusu eksportu 10 60 600
invoiceDownload Pobranie faktury po numerze KSeF 8 16 64
other Każdy pozostały chroniony zasób 10 30 120

Są to wartości domyślne, a nie stała konfiguracyjna, którą warto na zawsze skopiować do aplikacji. Uwierzytelniony punkt końcowy GET /rate-limits zwraca wartości obowiązujące dla bieżącego kontekstu. KSeF może zmienić limity, przyznać indywidualne zwiększenie albo tymczasowo podnieść wartości, które później wygasną. Komunikat Ministerstwa dla integratorów z kwietnia 2026 roku podaje, że indywidualne zmiany są stosowane jednocześnie w środowiskach DEMO i produkcyjnym.

Statyczna tabela przydaje się do planowania wydajności. Reguły działające w aplikacji oprzyj na GET /rate-limits, wynik zapisuj w pamięci podręcznej, a rzeczywistą odpowiedź 429 traktuj jako rozstrzygającą.

Dwie nieaktualne wartości do usunięcia ze starych procedur

Po pierwsze, domyślne limity środowiska TEST nie są już dziesięć razy wyższe od produkcyjnych. W API 2.5.0 limity wspólnych grup w TEST zrównano z produkcją, zachowując punkty końcowe dostępne wyłącznie w TEST, dzięki którym integratorzy mogą symulować własne profile. Stwierdzenie o dziesięciokrotnie wyższych limitach nadal występuje w opisowym przewodniku, ale historia zmian API i obowiązujące specyfikacje pokazują późniejszą zmianę.

Po drugie, oficjalny dokument PDF nadal podaje dla eksportu faktur 4 żądania na sekundę i 8 na minutę. W API 2.4.0 progi te zwiększono do 8 i 16 w środowisku produkcyjnym 16 kwietnia 2026 roku. Limit godzinowy pozostał na poziomie 20.

Wersja ma tu znaczenie. Gałąź main repozytorium zawiera już zmiany API 2.7.1, które 26 sierpnia wdrożono w TEST, ale ich wdrożenie produkcyjne zaplanowano na 23 września. Przy ustalaniu bieżącego działania produkcji obowiązujący kontrakt OpenAPI ma pierwszeństwo przed przyszłą zmianą w main.

Jak KSeF zlicza żądania?

Chronione żądania są zazwyczaj zliczane dla każdej kombinacji kontekstu KSeF i źródłowego adresu IP. Liczniki korzystają z okien kroczących, a nie ze stałych minut czy godzin zegarowych.

Oficjalny przewodnik po limitach żądań definiuje klucz limitu jako parę:

  • ContextIdentifier użytego podczas uwierzytelniania, na przykład Nip, InternalId lub NipVatUe;
  • publicznego adresu IP, z którego łączy się klient.

Ten sam NIP i jeden wyjściowy adres IP oznaczają wspólny limit dla wszystkich procesów i instancji roboczych korzystających z tego adresu. Inne biuro lub integrator używający tego samego kontekstu z innego IP otrzymuje oddzielny licznik. Limity publicznych punktów końcowych są przypisane do adresu IP.

Każde żądanie jest zliczane w poprzedniej sekundzie, 60 sekundach i 60 minutach. Okno minutowe nie zeruje się o 12:01:00, a godzinowe o pełnej godzinie. Jeśli limit 20 eksportów faktur na godzinę zostanie wykorzystany w pierwszych dziesięciu minutach, oczekiwanie do następnej pełnej godziny nie wystarczy. Przepustowość wraca, gdy poszczególne wywołania opuszczają kroczące okno 60 minut.

Dlatego samo uśpienie pojedynczego procesu nie wystarcza. Dziesięć procesów roboczych może niezależnie uznać, że nie przekracza limitu, choć ich łączny ruch wyczerpuje wspólną pulę (kontekst, IP). Mechanizm ograniczający ruch musi koordynować wszystkie procesy korzystające z tego samego klucza limitu i grupy operacji.

Nie obchodź limitów przez zmianę adresów IP. Ministerstwo wprost informuje, że rejestruje naruszenia i monitoruje systematyczne używanie wielu adresów do omijania progów. Powtarzające się lub skrajne przypadki mogą uruchomić szerszą ochronę dla podmiotu albo zakresu adresów IP.

Co zrobić po odpowiedzi HTTP 429?

Po otrzymaniu 429 Too Many Requests odczytaj Retry-After, zatrzymaj żądania korzystające z tej samej puli limitu i odczekaj co najmniej wskazaną liczbę sekund. Niewielki dodatni jitter możesz dodać po opóźnieniu wyznaczonym przez serwer, nigdy zamiast niego.

KSeF zwraca Retry-After jako całkowitą liczbę sekund. Blokada jest dynamiczna, a powtarzające się naruszenia mogą ją znacznie wydłużyć. Nie istnieje prawidłowa stała reguła zastępcza w rodzaju „zawsze ponów po 30 sekundach”.

Bezpieczny harmonogram działa w następującej kolejności:

quota_key = [context_identifier, egress_ip, limit_group]

on HTTP 429:
  retry_after = parse Retry-After as seconds
  pause quota_key until monotonic_now + retry_after
  requeue the operation after pause_until + small_positive_jitter
  record the attempt and stop after a bounded retry/time budget

Wspólne wstrzymanie jest istotne. Ponowne zakolejkowanie tylko procesu, który otrzymał odpowiedź, pozwala pozostałym nadal wyczerpywać ten sam limit. Jitter jest decyzją techniczną po stronie klienta, a nie wymogiem Ministerstwa. Rozkłada w czasie wybudzenie oczekujących procesów po obowiązkowym opóźnieniu, żeby nie ruszyły wszystkie w tej samej milisekundzie.

KSeF obsługuje dwa formaty treści błędu. Starsza odpowiedź JSON nadal jest dostępna. Klient może zażądać formatu Problem Details przez X-Error-Format: problem-details. W obu przypadkach harmonogram ponowienia wynika z nagłówka odpowiedzi, dlatego warstwa HTTP powinna zachować nagłówki również wtedy, gdy zamienia treść w typowany wyjątek.

Oficjalny klient C# odczytuje Retry-After i udostępnia zalecane opóźnienie. Jego repozytorium zawiera także warstwę ograniczania żądań, która pobiera obowiązujące limity, steruje ruchem z uwzględnieniem wszystkich trzech okien i po odpowiedzi 429 ponawia żądanie najwyżej pięć razy. Ta warstwa znajduje się w narzędziach testowych, nie w produkcyjnym potoku SDK. SDK dla Javy również udostępnia błąd i nagłówki, ale nie włącza ogólnej automatycznej pętli ponowień.

Oba klienty zawierają circuit breaker, który otwiera się po pięciu kolejnych przejściowych awariach, a po 30 sekundach dopuszcza próbne żądanie w stanie półotwartym. Circuit breaker nie jest polityką ponawiania. Szybko odrzuca wywołania, żeby chronić aplikację i KSeF; nie ponawia nieudanego żądania.

Które błędy ponawiać, które uzgadniać, a przy których się zatrzymać?

Przed ponowieniem sklasyfikuj wynik. Ograniczenie ruchu, trwająca operacja asynchroniczna, nieprawidłowe dane i niepewny wynik po błędzie sieci wymagają innych reakcji.

Wynik Znaczenie Bezpieczne działanie
HTTP 429 z Retry-After KSeF ograniczył operację Wstrzymaj ruch korzystający ze wspólnej puli limitu, odczekaj co najmniej wskazany czas i ponów w ramach ograniczonego budżetu
Status 100 lub 150 Operacja asynchroniczna została przyjęta i nadal jest przetwarzana Sprawdzaj status w kontrolowanym tempie z jitterem; nie wysyłaj ponownie
HTTP 400 lub błąd walidacji faktury Żądanie albo dokument są nieprawidłowe Popraw dane; nie ponawiaj żądania z tą samą treścią
HTTP 401 lub 403 Uwierzytelnienie albo autoryzacja nie powiodły się Napraw dane dostępowe lub uprawnienia przed ponowieniem
HTTP 408, 5xx, przekroczenie czasu albo utrata połączenia Awaria jest przejściowa, ale wynik zapisu może być nieznany Ponawiaj bezpieczne odczyty; przed powtórzeniem zapisu uzgodnij jego wynik
Końcowy status 550 KSeF anulował przetwarzanie i zaleca ponowienie Zachowaj poprzedni zapis korelacyjny, a następnie utwórz kontrolowane ponowne zgłoszenie
Status 440 KSeF wykrył duplikat faktury Uzgodnij stan na podstawie pierwotnych identyfikatorów sesji i KSeF; nie ponawiaj dalej

Tabela jest celowo bardziej rygorystyczna niż zasada „ponawiaj każdy błąd przejściowy”. Żądanie GET, które przekroczyło czas, zazwyczaj można powtórzyć. Żądanie POST, które wysłało dane przed zerwaniem połączenia, mogło już rozpocząć operację asynchroniczną.

Ustal zarówno limit prób, jak i opóźnienie. Kolejka ponawiająca bez końca ukrywa incydent i zużywa przepustowość potrzebną do obsługi pozostałych zadań. Po wyczerpaniu liczby prób lub budżetu czasu przenieś operację do widocznego stanu zablokowanego i powiadom operatora, przekazując dane korelacyjne potrzebne do bezpiecznego wznowienia.

Jak zapobiegać powielonej wysyłce faktur?

Wysyłka faktury do KSeF nie jest opisana jako idempotentna. Należy trwale zapisać lokalną próbę, skrót treści oraz identyfikatory sesji i faktury, a następnie uzgodnić niepewny wynik przed utworzeniem kolejnego zgłoszenia.

Kontrakt KSeF nie udostępnia nagłówka Idempotency-Key ani tokenu żądania klienta dla wysyłki faktury. Skrót SHA-256 faktury służy do kontroli integralności i korelacji; nie jest opisany jako klucz idempotencji.

Warto zastosować trwałą lokalną maszynę stanów:

  1. Utwórz próbę przed wysłaniem żądania. Zapisz identyfikator faktury źródłowej, skrót dokładnej treści żądania, kontekst, środowisko, typ operacji i numer próby.
  2. Natychmiast zapisuj identyfikatory. Otwarcie sesji interaktywnej zwraca referenceNumber sesji. Wysłanie faktury zwraca HTTP 202 z osobnym referenceNumber faktury. Zapisz każdy z nich przed zaplanowaniem kolejnego kroku.
  3. Odróżnij wysłanie od przetworzenia. Prawidłowa odpowiedź HTTP oznacza, że KSeF przyjął zadanie do przetwarzania. Nie oznacza jeszcze, że faktura otrzymała numer KSeF.
  4. Uzgadniaj zapisy o nieznanym wyniku. Jeśli odpowiedź zniknęła, sprawdź znaną sesję, jej faktury i zapisane skróty. Jeśli istnieje identyfikator faktury, sprawdzaj jego status.
  5. Twórz nową próbę dopiero po uzgodnieniu. Zachowaj wcześniejszą próbę i wyjaśnij, dlaczego ponowna wysyłka była konieczna.

Oficjalny przewodnik po trybie wsadowym zaleca lokalne powiązanie skrótu SHA-256 każdego oryginalnego pliku XML z dokumentem źródłowym. Rekordy faktur zwracane dla sesji zawierają skrót, identyfikator, numer faktury, status i opcjonalny numer KSeF, co pozwala dopasować wyniki bez zgadywania.

KSeF wykrywa również duplikaty globalnie na podstawie NIP-u sprzedawcy, rodzaju faktury i numeru faktury. Duplikat otrzymuje asynchroniczny status 440, a nie potwierdzenie kolejnej udanej wysyłki. Odpowiedź może zawierać originalSessionReferenceNumber i originalKsefNumber. Pola te pomagają naprawić stan po wykryciu duplikatu, ale nie czynią ponownej wysyłki operacją idempotentną.

Jak sterować sprawdzaniem statusu i pracą wsadową?

Dla każdej grupy limitów KSeF koordynuj ruch osobno, zachowuj zapas względem wszystkich progów kroczących i wybieraj operacje wsadowe, gdy w tym samym czasie gotowa jest więcej niż jedna faktura.

Zacznij od mechanizmu ograniczającego ruch według klucza (kontekst, wyjściowy adres IP, grupa limitów). Obowiązujące wartości pobieraj z GET /rate-limits, zapisuj w pamięci podręcznej i okresowo odświeżaj. Nie wywołuj punktu końcowego limitów przed każdym żądaniem, bo ono samo również jest operacją API.

Następnie warto rozdzielić następujące rodzaje obciążenia:

  • sterowanie sesją interaktywną;
  • interaktywne wysyłanie faktur;
  • sprawdzanie statusu faktur;
  • tworzenie eksportów i sprawdzanie ich statusu;
  • pobieranie faktur;
  • pozostałe chronione operacje.

Zachowuj świadomy zapas. Harmonogram wykorzystujący dokładnie 30 wysyłek na minutę nie zostawia miejsca na rozjazd zegarów, opóźnione wybudzenie zadań, inną instancję aplikacji ani ręczny ruch korzystający z tego samego NIP-u i IP.

Sprawdzanie statusu wymaga własnego budżetu. Punkt końcowy statusu jednej faktury dopuszcza 120 wywołań na minutę i 1 200 na godzinę, natomiast wyświetlenie wszystkich sesji tylko 10 na minutę i 60 na godzinę. Sprawdzaj konkretny, znany identyfikator zamiast wielokrotnie pobierać pełną listę. Gdy status wynosi 100 lub 150, stopniowo wydłużaj odstęp, dodaj jitter, ogranicz maksymalne opóźnienie i zakończ po wyniku końcowym albo upływie wyznaczonego czasu.

Dla wielu faktur Ministerstwo zaleca tryb wsadowy. Jeden pakiet zawierający 100 faktur zazwyczaj wykorzystuje limit żądań wydajniej niż 100 wysyłek interaktywnych. Wysyłanie części pakietu w otwartej sesji wsadowej nie wlicza się do limitów żądań API i może odbywać się równolegle, choć otwarcie i zamknięcie sesji wsadowej nadal podlega limitom.

Ta sama zasada dotyczy pobierania. Według KSeF systemy obsługujące dużą liczbę faktur powinny używać eksportów asynchronicznych i synchronizować dane z lokalną bazą. Wywoływanie KSeF za każdym razem, gdy użytkownik otwiera fakturę, zamienia centralne repozytorium w bazę aplikacyjną i niepotrzebnie zużywa niewielki limit pobierania.

Co monitorować w środowisku produkcyjnym?

Monitoruj wykorzystanie limitów, decyzje o ponowieniu, wyniki operacji asynchronicznych i stan przywracania prawidłowej pracy, ale nie zapisuj treści faktur ani danych uwierzytelniających. Sama liczba odpowiedzi 429 mówi, że system zareagował zbyt późno, lecz nie wyjaśnia dlaczego.

Minimalny zakres rejestrowanych danych obejmuje:

  • obowiązujące limity i czas ich ostatniego odświeżenia;
  • liczbę żądań według środowiska, kontekstu, wyjściowego adresu IP i grupy limitów;
  • liczbę 429, wartość Retry-After, numer próby i ostateczny wynik;
  • długość kolejek oraz wiek oczekujących zadań wysyłki, sprawdzania statusu, eksportu i pobierania;
  • czas od wysyłki do końcowego statusu faktury;
  • liczbę oczekujących statusów 100/150, duplikatów 440 i anulowanych operacji 550;
  • zapisy o nieznanym wyniku oczekujące na uzgodnienie;
  • stan circuit breakera i liczbę odrzuconych wywołań;
  • identyfikatory sesji, faktury, eksportu i lokalnej próby potrzebne w obsłudze zgłoszenia.

Nie zapisuj danych wrażliwych w logach ani systemach raportowania błędów. XML faktury, dane nabywcy, tokeny uwierzytelniające, dokumenty UPO, ciasteczka i surowe parametry żądania nie powinny trafiać do zdarzenia błędu. Do zdiagnozowania problemu z ponowieniem zazwyczaj wystarczą identyfikatory, przejścia stanów, klasa odpowiedzi, identyfikator śledzenia i czasy.

Alerty powinny dotyczyć trendów, nie tylko pojedynczych odpowiedzi. Rosnące szacowane wykorzystanie limitu godzinowego, wydłużająca się kolejka statusów albo powtarzające się wysokie wartości Retry-After dają czas na spowolnienie źródeł ruchu, zanim integracja wpadnie w lawinę ponowień.

Jak KSeF Kit obsługuje ponowienia obecnie?

KSeF Kit trwale zapisuje próby wysyłki i identyfikatory KSeF, dzięki czemu może wznowić sprawdzanie statusu bez ponownego wysyłania tej samej faktury w ciemno. Dokumentacja publiczna opisuje pięć ponowień z rosnącymi opóźnieniami dla przejściowych błędów 429, 500 i 550.

Cykl wysyłki zaczyna się od ostatecznie zatwierdzonej faktury Stripe, która stanowi niezmienne źródło danych. Następnie system mapuje ją do FA(3), otwiera sesję interaktywną, wysyła dokument i sprawdza status aż do otrzymania numeru KSeF oraz UPO. Każda próba wysyłki jest osobnym rekordem. Jeśli sprawdzanie zostanie przerwane, zapisane identyfikatory pozwalają późniejszemu zadaniu kontynuować obsługę przyjętej operacji.

Przewodnik po API KSeF i procedura na wypadek awarii odróżniają przejściowe ponowienia od uzgadniania wyniku. Widoczne dla użytkownika stany rozdzielają zadania zakolejkowane, wysyłane, przyjęte, odrzucone i zablokowane. Dokumentacja bezpieczeństwa podaje, że błędy hostowanej usługi zawierają w Sentry identyfikatory i stan, ale wykluczają treść faktur, dane osobowe nabywców, tokeny, UPO, parametry żądań i ciasteczka.

Na tym kończą się obecnie publicznie opisane możliwości produktu. KSeF Kit nie deklaruje budżetów żądań dla poszczególnych kontekstów, udokumentowanej polityki jittera, paneli limitów ani wystawiania w trybie offline24. Szersza architektura opisana w tym przewodniku wyznacza docelowy standard dla integracji produkcyjnej, nie listę ukrytych funkcji produktu.

Zasada jest prosta: kontroluj tempo, zanim zrobi to KSeF, respektuj opóźnienie po zatrzymaniu ruchu i nigdy nie myl ponawiania transmisji ze sprawdzaniem, czy faktura już istnieje.

Wysyłasz faktury Stripe do KSeF? KSeF Kit przekształca ostatecznie zatwierdzone faktury w FA(3), śledzi każdą próbę i przechowuje identyfikator KSeF oraz UPO razem z rekordem źródłowym.

Zacznij korzystać z KSeF Kit

Powiazane artykuly

Gotowy na madrzejsza rekrutacje?

Zacznij za darmo na 30 dni. Zrezygnuj przed końcem, a nie zapłacisz ani grosza. Skonfiguruj swój pierwszy pipeline rekrutacyjny w kilka minut.

Zacznij za darmo