Fakturnia Developers Szybki start Dokumentacja API English

Błędy

API używa standardowych kodów statusu HTTP oraz spójnej koperty błędu. Każdy błąd zawiera stabilny, czytelny maszynowo message (kod błędu) oraz, gdy ma to znaczenie, szczegóły w errors.

Struktura błędu

{
  "success": false,
  "data": null,
  "message": "AMBIGUOUS_PARTY",
  "executionTime": 5,
  "errors": ["Podaj albo buyerId, albo buyer, ale nie oba."]
}

Zawsze podejmuj decyzje na podstawie message (kodu), a nie czytelnego dla człowieka tekstu. Tekst może się zmienić, kod nie. Pole errors ma dwie postacie: przy walidacji pól to lista obiektów { field, code?, message }, w pozostałych przypadkach lista zdań wyjaśniających, np. ["REST API wymaga planu MAX."].

Kody statusu

Status Znaczenie
200 / 201 sukces
400 nieprawidłowe parametry zapytania lub ścieżki, operacja niedozwolona dla stanu dokumentu, a przy tworzeniu dokumentów także błędny kształt treści żądania (np. brak documentType, issueDate, products albo nabywcy)
401 brakujący, nieprawidłowy lub wygasły token, albo unieważnione konto API
403 uwierzytelniono, ale brak uprawnień: scope, plan MAX, lista dozwolonych adresów IP
404 nie znaleziono zasobu (także gdy należy do innego konta)
409 konflikt (np. numer dokumentu już istnieje, webhook dla adresu już zarejestrowany)
422 niepowodzenie walidacji treści żądania: brak pola, zły format, reguły zależne od typu, sprzeczne adnotacje (przy tworzeniu dokumentów część tych sprawdzeń zwraca 400, patrz VALIDATION_ERROR)
429 przekroczony limit żądań albo pełna kolejka renderowania PDF
500 nieoczekiwany błąd serwera
503 zewnętrzny rejestr chwilowo nie odpowiada (wyszukiwanie firmy w GUS); ponów za chwilę

Kody błędów

Kod Status Kiedy
UNAUTHORIZED 401 brakujący lub nieprawidłowy token; także token unieważnionego konta API
TOKEN_EXPIRED 401 token wygasł, pobierz nowy z /v1/oauth/token
NO_PERMISSIONS 403 token nie ma wymaganego scope (errors[0] podaje, którego)
SUBSCRIPTION_REQUIRED 403 konto bez aktywnego planu MAX (całe REST API jest modułem MAX)
FORBIDDEN 403 adres IP spoza listy dozwolonych dla konta API
DOCUMENT_LIMIT_EXCEEDED 403 plan konta nie pozwala wystawiać ani edytować dokumentów (errors[0] zaczyna się od „Subskrypcja nieaktywna” albo „Subskrypcja wygasła”)
VALIDATION_ERROR 422 / 400 treść żądania nie przeszła walidacji; szczegóły w errors. Zwykle 422, ale tworzenie dokumentów (POST /documents, POST /documents/validate) i dokumentów magazynowych (POST /warehouse/documents, POST /warehouse/documents/validate) zwraca 400 przy błędach kształtu żądania (brak documentType, issueDate albo products, zły format daty, błędna pozycja). Traktuj oba statusy z tym kodem jako błąd walidacji
PARTIAL_PAYMENTS_INVALID 422 zapłaty częściowe nie zgadzają się z kwotą albo statusem płatności
DOCUMENT_DATES_INVALID 422 daty dokumentu przeczą sobie albo ustawie o VAT (okres sprzedaży, data sprzedaży ponad 60 dni po wystawieniu, zapłata po wystawieniu, korekta przed fakturą korygowaną)
PAYMENT_INSTALLMENTS_INVALID 422 raty nie zgadzają się z kwotą do zapłaty, terminami albo statusem płatności, albo paymentInstallmentsSplit nie da się wykonać (np. kwota za mała na tyle rat)
PARTY_IDENTIFIER_INVALID 422 identyfikatory nabywcy albo odbiorcy podanych danymi przy dokumencie są sprzeczne (np. nip z numerem DE…, vatEu z numerem PL… albo XI…, błędna cyfra kontrolna NIP-u, idWew u nabywcy); errors podaje pole, np. buyer.vatUE. Kontrahenci (/clients) zwracają takie błędy jako VALIDATION_ERROR. Zob. Identyfikatory kontrahenta
ADVANCE_RECEIPTS_INVALID 422 wpłaty na fakturze zaliczkowej nie zgadzają się z kwotą zaliczki, datami albo kursami
INVALID_PARAMS 400 nieprawidłowe parametry zapytania (np. nieznany documentType, zła data)
BAD_REQUEST 400 brak wymaganego elementu żądania poza walidacją pól
AMBIGUOUS_PARTY 400 podano jednocześnie buyerId i buyer (albo receiverId i receiver)
BUYER_REQUIRED 400 nie podano ani buyerId, ani buyer
NOT_FOUND / DOCUMENT_NOT_FOUND 404 brak zasobu
DOCUMENT_NUMBER_EXISTS 409 numer zajęty w swojej serii albo ten sam pełny numer ma już inny dokument na koncie
CONFLICT 409 stan zasobu nie pozwala na operację (np. jedyny magazyn, webhook dla adresu już istnieje, zakończona reguła cykliczna)
KSEF_CONFIRMED 400 usunięcie/edycja dokumentu już zatwierdzonego w KSeF (posiada numer KSeF)
KSEF_SENT 400 usunięcie/edycja dokumentu wysłanego do KSeF i oczekującego na potwierdzenie
DOCUMENT_CORRECTED 409 edycja albo usunięcie faktury, do której istnieje korekta (zmianę wprowadza kolejna korekta)
CORRECTED_INVOICE_HAS_CORRECTION 409 nowa korekta dokumentu, który ma już korektę (kolejną zmianę wystaw jako korektę jego ostatniej korekty, numer i id w errors[0])
ADVANCE_INVOICE_SETTLED 409 edycja albo usunięcie faktury zaliczkowej rozliczonej fakturą rozliczeniową
ORDER_HAS_ADVANCE_INVOICES 400 edycja albo usunięcie zamówienia z wystawionymi fakturami zaliczkowymi
WAREHOUSE_LINES_LOCKED 409 zmiana pozycji dokumentu magazynowego przez PUT/PATCH (usuń i wystaw nowy)
STOCK_SHORTAGE 422 WZ/RW/MM zeszłoby ze stanem poniżej zera (allowNegativeStock: true wystawia mimo braku)
WAREHOUSE_INVALID 422 nieznany albo cudzy magazyn, MM bez magazynu docelowego albo z tym samym magazynem
PRODUCT_NOT_FOUND 404 pozycja dokumentu magazynowego wskazuje nieznany produkt
KSEF_CONNECTION_REQUIRED 409 wysyłka bez skonfigurowanego połączenia z KSeF
KSEF_CONNECTION_NOT_AUTHORIZED 422 połączenie istnieje, ale nie przeszło autoryzacji
KSEF_ALREADY_PROCESSING / KSEF_SEND_NOT_ALLOWED 409 wysyłka w toku albo dokument w stanie niepozwalającym na wysyłkę
INVALID_PAYMENT_STATUS / PAYMENT_STATUS_UPDATE_NOT_ALLOWED 400 zła wartość receivedPayment albo dokument nie jest „Do zapłaty”
EMAIL_TAKEN / EMPLOYEE_LIMIT_REACHED 409 e-mail pracownika zajęty albo limit 20 kont
INVALID_NIP / COMPANY_NOT_FOUND 400 / 404 wyszukiwanie firmy po NIP
GUS_UNAVAILABLE 503 rejestr GUS nie odpowiada przy wyszukiwaniu firmy po NIP; ponów za chwilę
RATE_LIMIT_EXCEEDED 429 przekroczony limit zapytań, ponów po Retry-After (zobacz Limity zapytań)
WAIT_PDF_QUEUE 429 pełna kolejka renderowania PDF, ponów po Retry-After (zobacz Kolejka renderowania PDF)
INTERNAL_SERVER_ERROR 500 nieoczekiwany, bezpieczny do idempotentnego ponowienia

Pełna tabela kodów ze statusami jest też na górze specyfikacji OpenAPI (info.description).

Nagłówki odpowiedzi

Każda odpowiedź niesie nagłówek X-Request-ID z unikalnym identyfikatorem żądania. Zapisuj go w logach integracji i podawaj w zgłoszeniach do pomocy: pozwala odnaleźć konkretne wywołanie po stronie Fakturnii. Nagłówki X-RateLimit-* i Retry-After opisuje strona Limity zapytań, a Idempotent-Replayed strona Idempotentność.

Obsługa błędów

const res = await fetch(url, opts);
const body = await res.json();

if (!body.success) {
  switch (body.message) {
    case 'TOKEN_EXPIRED':           // refresh the token and retry once
    case 'UNAUTHORIZED':            // re-authenticate; a revoked API account needs a new one
    case 'SUBSCRIPTION_REQUIRED':   // the account needs the MAX plan; tell the user, do not retry
    case 'RATE_LIMIT_EXCEEDED':     // wait Retry-After seconds, then retry
    case 'DOCUMENT_NUMBER_EXISTS':  // pick a new number or let the API auto-number
    case 'VALIDATION_ERROR':        // 400 or 422: inspect body.errors
    default:
      throw new Error(`${body.message} [${res.headers.get('X-Request-ID')}]: ${JSON.stringify(body.errors ?? [])}`);
  }
}

Błędy 5xx i 429 można bezpiecznie ponawiać z odczekiwaniem (backoff) wtedy, gdy żądanie zawierało Idempotency-Key. Zobacz Idempotentność.