{
  "openapi": "3.0.3",
  "info": {
    "title": "Fakturnia External REST API",
    "version": "1.3.0",
    "description": "\nOficjalne API pozwalające na integrację z systemem Fakturnia.\n\n## 💎 Plan MAX\nREST API (konta API, wszystkie endpointy `/external/v1`, webhooki) jest modułem planu **MAX**. Bez aktywnego planu MAX endpoint tokenu odpowiada `403 access_denied` z `error_code: SUBSCRIPTION_REQUIRED`, a każde wywołanie z wcześniej wydanym tokenem `403 SUBSCRIPTION_REQUIRED`. Webhooki nie są wtedy wysyłane.\n\n## 📦 Koperta odpowiedzi i kody błędów\nKażda odpowiedź JSON ma kształt `{ success, data, message, executionTime, errors? }`. Przy błędzie `message` jest **stałym kodem** (rozgałęziaj logikę po nim, nie po tekście), a `errors` zawiera szczegóły: obiekty `{ field, code?, message }` przy walidacji pól albo zdania wyjaśniające.\n\n| Kod | Status |\n|---|---|\n| `BAD_REQUEST` | 400 |\n| `INVALID_NIP` | 400 |\n| `INVALID_PARAMS` | 400 |\n| `INVALID_PAYMENT_STATUS` | 400 |\n| `KSEF_CONFIRMED` | 400 |\n| `KSEF_SENT` | 400 |\n| `PAYMENT_STATUS_UPDATE_NOT_ALLOWED` | 400 |\n| `INVALID_API_KEY` | 401 |\n| `TOKEN_EXPIRED` | 401 |\n| `UNAUTHORIZED` | 401 |\n| `DOCUMENT_LIMIT_EXCEEDED` | 403 |\n| `FORBIDDEN` | 403 |\n| `NO_PERMISSIONS` | 403 |\n| `SUBSCRIPTION_REQUIRED` | 403 |\n| `COMPANY_NOT_FOUND` | 404 |\n| `DOCUMENT_NOT_FOUND` | 404 |\n| `KSEF_CONNECTION_NOT_FOUND` | 404 |\n| `NOT_FOUND` | 404 |\n| `PRODUCT_NOT_FOUND` | 404 |\n| `USER_NOT_FOUND` | 404 |\n| `USER_OR_NIP_NOT_FOUND` | 404 |\n| `ADVANCE_INVOICE_SETTLED` | 409 |\n| `CONFLICT` | 409 |\n| `CORRECTED_INVOICE_HAS_CORRECTION` | 409 |\n| `DOCUMENT_CORRECTED` | 409 |\n| `DOCUMENT_NUMBER_EXISTS` | 409 |\n| `EMAIL_TAKEN` | 409 |\n| `EMPLOYEE_LIMIT_REACHED` | 409 |\n| `KSEF_ALREADY_PROCESSING` | 409 |\n| `KSEF_CONNECTION_REQUIRED` | 409 |\n| `KSEF_SEND_NOT_ALLOWED` | 409 |\n| `WAREHOUSE_LINES_LOCKED` | 409 |\n| `ADVANCE_RECEIPTS_INVALID` | 422 |\n| `DOCUMENT_DATES_INVALID` | 422 |\n| `KSEF_CONNECTION_NOT_AUTHORIZED` | 422 |\n| `MARGIN_LINE_NOT_FOUND` | 422 |\n| `MARGIN_PURCHASES_INVALID` | 422 |\n| `PARTIAL_PAYMENTS_INVALID` | 422 |\n| `PAYMENT_INSTALLMENTS_INVALID` | 422 |\n| `STOCK_SHORTAGE` | 422 |\n| `VALIDATION_ERROR` | 422 |\n| `WAREHOUSE_INVALID` | 422 |\n| `RATE_LIMIT_EXCEEDED` | 429 |\n| `WAIT_PDF_QUEUE` | 429 |\n| `INTERNAL_SERVER_ERROR` | 500 |\n| `GUS_UNAVAILABLE` | 503 |\n\n## 🧾 Nagłówki odpowiedzi\n- `X-Request-ID`: identyfikator żądania (podaj go w zgłoszeniu do pomocy),\n- `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`: stan limitu zapytań,\n- `Retry-After`: przy `429` liczba sekund do ponowienia,\n- `Idempotent-Replayed: true`: odpowiedź odtworzona z wcześniejszego żądania o tym samym `Idempotency-Key`.\n\n## 🔑 Uprawnienia (OAuth Scopes)\nDo wywoływania endpointów API wymagane są odpowiednie uprawnienia nadawane podczas tworzenia Konta API. Wymagane uprawnienie jest widoczne przy każdym z endpointów.\n\n### Dostępne uprawnienia\n- `documents:browse` - Wyszukiwanie dokumentów\n- `documents:read` - Pobieranie dokumentu po ID\n- `documents:download` - Pobieranie PDF dokumentu\n- `documents:create` - Tworzenie dokumentów\n- `documents:delete` - Usuwanie dokumentów\n- `documents:update` - Edycja dokumentów\n- `documents:update-payment-status` - Zmiana statusu płatności dokumentu\n- `documents:update-external-reference` - Powiązanie dokumentu z zamówieniem zewnętrznym\n- `documents:send-to-ksef` - Wysyłka dokumentów do KSeF\n- `ksef:read` - Podgląd statusu połączenia KSeF\n- `ksef:configure` - Konfiguracja połączenia KSeF\n- `ksef:test` - Test połączenia KSeF\n- `webhooks:read` - Podgląd webhooków i historii dostaw\n- `webhooks:create` - Tworzenie webhooków\n- `webhooks:update` - Edycja webhooków, rotacja sekretu i wysyłka testowa\n- `webhooks:delete` - Usuwanie webhooków\n- `email-accounts:browse` - Lista podłączonych kont pocztowych\n- `email-accounts:read` - Szczegóły konta pocztowego\n- `settings:read` - Podgląd ustawień\n- `settings:update` - Edycja ustawień\n- `gus:company:read` - Pobieranie danych firmy po NIP z GUS\n- `clients:browse` - Wyszukiwanie klientów\n- `clients:read` - Pobieranie klienta po ID\n- `clients:create` - Tworzenie klientów\n- `clients:update` - Edycja klientów\n- `clients:delete` - Usuwanie klientów\n- `products:browse` - Wyszukiwanie produktów\n- `products:read` - Pobieranie produktu po ID\n- `products:create` - Tworzenie produktów\n- `products:update` - Edycja produktów\n- `products:delete` - Usuwanie produktów\n- `warehouse:browse` - Lista magazynów\n- `warehouse:create` - Tworzenie magazynów\n- `warehouse:update` - Edycja magazynów\n- `warehouse:delete` - Usuwanie magazynów\n- `warehouse:stock:read` - Raport stanów magazynowych\n- `warehouse:adjust` - Korekty stanów (inwentaryzacja)\n- `warehouse:wz:create` - Wystawianie WZ do faktur\n- `warehouse:documents:create` - Wystawianie dokumentów magazynowych (WZ, PZ, PW, RW, MM)\n- `employees:browse` - Lista kont pracowniczych\n- `employees:create` - Tworzenie kont pracowniczych\n- `employees:update` - Edycja kont pracowniczych i uprawnień\n- `employees:delete` - Usuwanie kont pracowniczych\n- `recurring:browse` - Lista reguł cyklicznych\n- `recurring:read` - Szczegóły reguły i historia generacji\n- `recurring:toggle` - Pauza i wznowienie reguły\n- `activity:read` - Historia aktywności konta (właściciel i pracownicy)\n\n## 🪝 Webhooki i weryfikacja autentyczności (X-Webhook-Signature)\nSystem wysyła powiadomienia do zdefiniowanych webhooków, gdy zajdą odpowiednie zdarzenia w systemie. Aby zweryfikować, czy żądanie faktycznie pochodzi z systemu Fakturnia, powinieneś walidować podpis wiadomości.\n\n### Jak to działa?\nKażda dostawa to `POST` z treścią JSON (schemat `WebhookEventPayload`): `{ id, event, timestamp, data, resourceId }`. Pole `id` (powtórzone w nagłówku `X-Webhook-Delivery`) jest takie samo przy każdym ponowieniu, więc służy do deduplikacji. Nagłówek `X-Webhook-Event` niesie nazwę zdarzenia, a `X-Webhook-Signature` podpis: hash **HMAC SHA-256** z surowego ciała żądania i sekretu webhooka (zwracanego raz, przy utworzeniu i przy rotacji).\n\n### Przykład weryfikacji w Node.js (Express)\n```javascript\nconst crypto = require('crypto');\nconst express = require('express');\nconst app = express();\n\nconst WEBHOOK_SECRET = 'twój_sekret_webhooka';\n\napp.post('/webhook-endpoint', express.raw({type: 'application/json'}), (req, res) => {\n    const signatureFromHeader = req.headers['x-webhook-signature'];\n    const expectedSignature = crypto.createHmac('sha256', WEBHOOK_SECRET).update(req.body).digest('hex');\n\n    if (signatureFromHeader !== expectedSignature) return res.status(401).send('Unauthorized');\n\n    const payload = JSON.parse(req.body.toString());\n    console.log('Zdarzenie:', payload.event);\n    res.status(200).send('OK');\n});\n```\n\n### Mechanizm ponawiania (Retry Mechanism)\nW przypadku gdy serwer docelowy (twój endpoint) nie odpowie statusem `200 OK`, system Fakturnia zakolejkuje zdarzenie do ponownej wysyłki.\nMechanizm podejmie maksymalnie 5 prób doręczenia webhooka, w następujących odstępach czasu:\n1. Natychmiastowa próba\n2. Po 5 minutach\n3. Po 30 minutach\n4. Po 2 godzinach\n5. Po 8 godzinach\n\nJeżeli po 5 próbie serwer nadal nie odpowie poprawnie (status 200), zdarzenie zostanie oznaczone jako zakończone niepowodzeniem (`FAILED`), a po 10 następujących po sobie niepowodzeniach dla tego samego webhooka (niezależnie od zdarzenia), webhook zostanie automatycznie wyłączony.\n\n### Lista zdarzeń\n- `client.created` - Gdy nowy kontrahent zostanie dodany\n- `client.updated` - Gdy dane kontrahenta zostaną zaktualizowane\n- `client.deleted` - Gdy kontrahent zostanie usunięty\n- `product.created` - Gdy produkt zostanie dodany\n- `product.updated` - Gdy dane produktu ulegną zmianie\n- `product.deleted` - Gdy produkt zostanie usunięty\n- `document.created` - Gdy dokument zostanie utworzony\n- `document.updated` - Gdy dokument zostanie zmodyfikowany\n- `document.deleted` - Gdy dokument zostanie usunięty\n- `document.sentToKSeF` - Gdy dokument zostanie przyjęty przez KSeF (ma numer KSeF)\n- `document.ksefRejected` - Gdy KSeF odrzuci dokument albo wysyłka zakończy się błędem\n- `document.paymentStatusChanged` - Gdy zmieni się oznaczenie zapłaty dokumentu (otrzymano / cofnięto)\n- `document.ksefImported` - Gdy synchronizacja z KSeF pobierze nowe faktury (otrzymane albo wystawione poza Fakturnią); identyfikatory w documentIds, do 100 w jednej dostawie\n        "
  },
  "servers": [
    {
      "url": "https://prod.api.fakturnia.pl/external/v1",
      "description": "Produkcja"
    },
    {
      "url": "https://sandbox.api.fakturnia.pl/external/v1",
      "description": "Środowisko testowe (sandbox) — wysyłki do KSeF bez skutków prawnych"
    }
  ],
  "components": {
    "schemas": {
      "CreateDocumentRequestBody": {
        "type": "object",
        "required": [
          "documentType",
          "issueDate"
        ],
        "properties": {
          "documentType": {
            "type": "string",
            "enum": [
              "Faktura",
              "FakturaVAT",
              "FakturaKorygujaca",
              "FakturaKorygujacaZaliczkowa",
              "FakturaKorygujacaRozliczeniowa",
              "FakturaZaliczka",
              "FakturaRozliczeniowa",
              "FakturaProforma",
              "FakturaProformaBezVAT",
              "Zamowienie"
            ],
            "description": "Typ dokumentu",
            "example": "FakturaVAT"
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "description": "Data wystawienia (ISO 8601)",
            "example": "2026-05-07"
          },
          "documentNo": {
            "type": "integer",
            "minimum": 1,
            "description": "Opcjonalny numer dokumentu. Jeśli podany, zostanie użyty zamiast automatycznej numeracji.",
            "example": 1
          },
          "numberingFormat": {
            "type": "string",
            "enum": [
              "/MM/YYYY",
              "YYYY/MM/",
              "/YYYY/MM",
              "MM/YYYY/",
              "/YYYY",
              "YYYY/",
              "-MM-YYYY",
              "YYYY-MM-",
              "-YYYY-MM",
              "MM-YYYY-",
              "-YYYY",
              "YYYY-"
            ],
            "description": "Format numeracji (np. \"/MM/YYYY\"). Domyślnie z ustawień użytkownika.",
            "example": "/MM/YYYY"
          },
          "symbol": {
            "type": "string",
            "description": "Prefiks symbolu dokumentu (np. \"FV/\"). Domyślnie z ustawień.",
            "example": "FV/"
          },
          "documentNumber": {
            "type": "string",
            "description": "Pełny numer dokumentu do walidacji 1:1. Jeśli podany razem z documentNo, musi być spójny.",
            "example": "FV/1/05/2026"
          },
          "invoiceName": {
            "type": "string",
            "description": "Nazwa faktury (np. dla FV zaliczkowych)",
            "example": "Faktura zaliczkowa"
          },
          "buyerId": {
            "type": "string",
            "description": "ID istniejącego klienta w systemie. Nie stosować razem z buyer. Wymagane buyerId albo buyer (poza korektą, która przejmuje nabywcę z korygowanej faktury).",
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "buyer": {
            "$ref": "#/components/schemas/ClientReference"
          },
          "receiverId": {
            "type": "string",
            "description": "ID opcjonalnego odbiorcy (dla faktur z wieloma stronami)."
          },
          "receiver": {
            "$ref": "#/components/schemas/ClientReference"
          },
          "products": {
            "type": "array",
            "description": "Pozycje dokumentu. Korekty: pełna lista pozycji PO korekcie (sumy dokumentu to różnica względem korygowanej faktury). FakturaZaliczka: pomiń, pozycje to rozkład zaliczki na stawki VAT zamówienia.",
            "items": {
              "type": "object",
              "required": [
                "name",
                "unitOfMeasure",
                "quantity"
              ],
              "properties": {
                "name": {
                  "type": "string",
                  "example": "Usługa programistyczna"
                },
                "gtu": {
                  "type": "string",
                  "nullable": true,
                  "enum": [
                    "GTU_01",
                    "GTU_02",
                    "GTU_03",
                    "GTU_04",
                    "GTU_05",
                    "GTU_06",
                    "GTU_07",
                    "GTU_08",
                    "GTU_09",
                    "GTU_10",
                    "GTU_11",
                    "GTU_12",
                    "GTU_13",
                    null
                  ],
                  "description": "Kod GTU (opcjonalny)"
                },
                "pkwiu": {
                  "type": "string",
                  "nullable": true
                },
                "unitOfMeasure": {
                  "type": "string",
                  "example": "szt."
                },
                "quantity": {
                  "type": "number",
                  "example": 1
                },
                "netPrice": {
                  "type": "number",
                  "nullable": true,
                  "description": "Cena jednostkowa netto. Gdy podana, wartości netValue/amountOfVat/grossValue są wyliczane automatycznie.",
                  "example": 100
                },
                "grossPrice": {
                  "type": "number",
                  "nullable": true,
                  "description": "Cena jednostkowa brutto (alternatywa dla netPrice).",
                  "example": 123
                },
                "netValue": {
                  "type": "number",
                  "nullable": true,
                  "description": "Opcjonalne, wartości mogą zostać przeliczone automatycznie.",
                  "example": 100
                },
                "grossValue": {
                  "type": "number",
                  "nullable": true,
                  "description": "Opcjonalne, wartości mogą zostać przeliczone automatycznie.",
                  "example": 123
                },
                "amountOfVat": {
                  "type": "number",
                  "nullable": true,
                  "description": "Opcjonalne, wartości mogą zostać przeliczone automatycznie.",
                  "example": 23
                },
                "vatRate": {
                  "oneOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "string"
                    }
                  ],
                  "example": 23,
                  "description": "Stawka VAT zgodna ze słownikiem AppData.VatRates. Wartość jest walidowana, a taxSymbol generowany automatycznie. Brak = domyślna stawka konta (settings.defaultTaxRate). \"marza\" = pozycja w procedurze marży (art. 119 i 120 ustawy o VAT): podaj grossPrice, faktura pokazuje tylko kwoty brutto, w KSeF suma trafia do P_13_11; wymaga annotations.marginProcedure (inaczej 422 MARGIN_LINE_WITHOUT_PROCEDURE)."
                },
                "marginPurchaseValue": {
                  "type": "number",
                  "nullable": true,
                  "minimum": 0,
                  "description": "Tylko vatRate \"marza\": kwota nabycia całej pozycji brutto w PLN (towar używany: cena zakupu; biuro podróży: koszty usług nabytych dla turysty). Nie trafia na fakturę ani do KSeF; służy do marży i VAT od marży w rejestrze VAT i JPK. Brak = do uzupełnienia później. W korekcie pominięta: przejmowana z korygowanej pozycji o tej nazwie, proporcjonalnie do ilości.",
                  "example": 3000
                },
                "marginTaxRate": {
                  "type": "number",
                  "nullable": true,
                  "enum": [
                    23,
                    8,
                    5,
                    0,
                    null
                  ],
                  "description": "Tylko vatRate \"marza\": stawka VAT liczona od marży (VAT = marża × stawka / (100 + stawka); ujemna marża = VAT 0). Domyślnie 23.",
                  "example": 23
                },
                "discount": {
                  "type": "number",
                  "example": 0
                },
                "currency": {
                  "type": "string",
                  "example": "PLN"
                }
              }
            }
          },
          "useAccountDefaults": {
            "type": "boolean",
            "description": "Domyślnie true: brakujące pola dostają wartości z ustawień konta jak nowy dokument w aplikacji (uwagi, podpisy, miejsce wystawienia, automatyczne adnotacje MPP/marża z rachunkiem VAT, podstawa zwolnienia dla stawki zw, forma i status płatności, stawka VAT pozycji). Pole podane jawnie zawsze wygrywa. false = bez wartości domyślnych konta. Korekta i tak przejmuje nabywcę, odbiorcę, walutę i adnotacje z korygowanej faktury, jeśli ich nie podasz.",
            "example": true
          },
          "currency": {
            "type": "string",
            "description": "Waluta dokumentu (ISO 4217)",
            "example": "PLN"
          },
          "exchangeRate": {
            "type": "number",
            "description": "Kurs wymiany dla walut obcych"
          },
          "issuePlace": {
            "type": "string",
            "description": "Miejsce wystawienia",
            "example": "Warszawa"
          },
          "comments": {
            "type": "string",
            "description": "Uwagi do dokumentu"
          },
          "paymentDescription": {
            "type": "string",
            "description": "Opis płatności"
          },
          "showPaymentSection": {
            "type": "boolean",
            "description": "Czy pokazywać sekcję płatności na dokumencie/PDF. Dla Zamowienie można ustawić false."
          },
          "paymentDeadlineDate": {
            "type": "string",
            "format": "date",
            "description": "Termin płatności (wymagany gdy paymentStatusId=1). Przy statusie Zapłacono jest ignorowany."
          },
          "additionalPaymentDate": {
            "type": "string",
            "format": "date",
            "description": "Data otrzymania zapłaty (wymagana gdy paymentStatusId=0). Przy statusie Do zapłaty jest ignorowana."
          },
          "additionalPaymentDateHeaderId": {
            "type": "number",
            "description": "ID nagłówka daty płatności ze słownika paymentDateHeaders. Dla paymentStatusId=0 domyślnie ustawiane jest id=2 (\"Data otrzymania zapłaty\").",
            "example": 2
          },
          "subDate": {
            "type": "string",
            "format": "date",
            "description": "Data sprzedaży / świadczenia usług. Dla faktur KSeF i Zamówienia domyślnie przyjmowana jest issueDate, jeśli nie podasz."
          },
          "subDateHeaderId": {
            "type": "number",
            "description": "ID nagłówka daty sprzedaży ze słownika additionalDateHeaders (np. 1 => \"Data wykonania usługi\").",
            "example": 1
          },
          "subDateTo": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Koniec okresu sprzedaży (KSeF OkresFa, P_6_Do). Z nim subDate jest początkiem okresu, np. usługa za cały miesiąc. Bez niego subDate to jedna data sprzedaży (P_6). Faktura korygująca bez subDate przejmuje datę albo okres sprzedaży korygowanej faktury."
          },
          "taxPointRule": {
            "type": "string",
            "nullable": true,
            "enum": [
              "art19a5p3a",
              "art19a5p3b",
              "art19a5p3c",
              "art19a5p4",
              null
            ],
            "description": "Obowiązek podatkowy z datą wystawienia faktury (art. 19a ust. 5 ustawy o VAT): art19a5p3a usługi budowlane (najpóźniej 30. dnia od wykonania), art19a5p3b dostawa książek i prasy (60. dnia), art19a5p3c druk książek i prasy (90. dnia), art19a5p4 media, telekomunikacja, najem, dzierżawa, leasing, ochrona, stała obsługa prawna i biurowa (najpóźniej z upływem terminu płatności). Nie trafia do KSeF; decyduje o okresie w raportach VAT i o dniu kursu waluty. null = zwykłe zasady (data sprzedaży)."
          },
          "exchangeRateDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Dzień tabeli NBP, z której jest exchangeRate. Według art. 31a ustawy o VAT to ostatni dzień roboczy przed dniem powstania obowiązku podatkowego (zwykle przed datą sprzedaży), a gdy faktura jest wcześniejsza, przed datą wystawienia. Korekta bez exchangeRate przejmuje kurs, jego dzień i tabelę z korygowanej faktury (art. 31b ust. 1)."
          },
          "exchangeRateTable": {
            "type": "string",
            "nullable": true,
            "maxLength": 32,
            "example": "190/A/NBP/2026",
            "description": "Numer tabeli NBP kursu exchangeRate, drukowany na PDF obok kursu."
          },
          "paymentInstallments": {
            "type": "array",
            "maxItems": 100,
            "description": "Raty o własnych kwotach (np. większa pierwsza rata): co najmniej dwa terminy płatności z kwotami (KSeF TerminPlatnosci, kwoty rat trafiają do DodatkowyOpis). Tylko przy paymentStatusId=1; suma rat musi być równa kwocie do zapłaty co do grosza, terminy po kolei i nie wcześniej niż data wystawienia. Bez paymentDeadlineDate terminem płatności dokumentu jest pierwsza rata. Równe raty: zamiast liczyć kwoty, podaj paymentInstallmentsSplit (nie łącz obu pól).",
            "items": {
              "type": "object",
              "required": [
                "date",
                "amount"
              ],
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-10-20"
                },
                "amount": {
                  "type": "number",
                  "example": 615
                }
              }
            }
          },
          "paymentInstallmentsSplit": {
            "type": "object",
            "nullable": true,
            "required": [
              "count"
            ],
            "description": "Równe raty wyliczone przez API: zalecane zawsze, gdy raty mają być równe. Podaj liczbę rat, a API po wyliczeniu sum dokumentu podzieli kwotę do zapłaty co do grosza: każda rata dostaje tyle samo, a grosze z zaokrąglenia trafiają do ostatniej (100,00 na 3 raty = 33,33 + 33,33 + 33,34). Dokument zapisuje zwykłe paymentInstallments (są w odpowiedzi i w podglądzie), a termin płatności (paymentDeadlineDate) to data pierwszej raty. Tylko przy paymentStatusId=1; przy tworzeniu bez paymentStatusId dokument dostaje status Do zapłaty. Raty o różnych kwotach (np. większa pierwsza rata) podaj w paymentInstallments; obu pól naraz nie łącz. PATCH bez products dzieli kwotę zapisaną w dokumencie. Błędy: 422 PAYMENT_INSTALLMENTS_INVALID. null = bez podziału.",
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 2,
                "maximum": 100,
                "example": 3,
                "description": "Liczba rat, od 2 do 100 (limit KSeF)."
              },
              "firstDate": {
                "type": "string",
                "format": "date",
                "example": "2026-10-21",
                "description": "Termin pierwszej raty, nie wcześniej niż data wystawienia. Domyślnie paymentDeadlineDate z żądania; przy aktualizacji zapisany termin płatności dokumentu do zapłaty; bez nich data wystawienia + 14 dni."
              },
              "every": {
                "type": "string",
                "enum": [
                  "month",
                  "week",
                  "14days"
                ],
                "default": "month",
                "example": "month",
                "description": "Odstęp między ratami: month co miesiąc (liczone od pierwszej daty: 31.01, 28.02, 31.03), week co 7 dni, 14days co 14 dni. Domyślnie month."
              }
            }
          },
          "paymentDeadlineTerm": {
            "type": "object",
            "nullable": true,
            "description": "Termin płatności opisany słowami (KSeF TerminOpis), np. 14 dni od dnia wystawienia faktury. Drukowany obok daty terminu.",
            "required": [
              "count",
              "unit",
              "event"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9999,
                "example": 14
              },
              "unit": {
                "type": "string",
                "enum": [
                  "day",
                  "week",
                  "month"
                ],
                "example": "day"
              },
              "event": {
                "type": "string",
                "enum": [
                  "issue",
                  "invoice_delivery",
                  "supply",
                  "acceptance"
                ],
                "example": "issue",
                "description": "Od czego liczy się termin: issue wystawienie faktury, invoice_delivery doręczenie faktury, supply dostawa towaru lub wykonanie usługi, acceptance odbiór."
              }
            }
          },
          "advanceReceipts": {
            "type": "array",
            "maxItems": 31,
            "description": "Faktura zaliczkowa dokumentująca kilka wpłat (KSeF ZaliczkaCzesciowa): co najmniej dwie wpłaty z datami otrzymania nie późniejszymi niż data wystawienia i sumą równą advancePaymentAmount, przy paymentStatusId=0. W walucie obcej każda wpłata ma swój kurs z dnia roboczego przed jej otrzymaniem (art. 31a). Każda wpłata to osobny obowiązek podatkowy w raportach VAT. Przy innych typach pole jest pomijane.",
            "items": {
              "type": "object",
              "required": [
                "date",
                "amount"
              ],
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-09-10"
                },
                "amount": {
                  "type": "number",
                  "example": 500
                },
                "exchangeRate": {
                  "type": "number",
                  "nullable": true,
                  "example": 4.4512
                },
                "exchangeRateDate": {
                  "type": "string",
                  "format": "date",
                  "nullable": true,
                  "example": "2026-09-09"
                }
              }
            }
          },
          "bankAccounts": {
            "type": "array",
            "description": "Konta bankowe do pokazania na dokumencie. Pierwsze konto trafia do bankAccountNumber, kolejne do additionalBankAccounts.",
            "items": {
              "type": "object",
              "required": [
                "accountNumber"
              ],
              "properties": {
                "bank": {
                  "type": "string",
                  "nullable": true
                },
                "accountNumber": {
                  "type": "string"
                },
                "swift": {
                  "type": "string"
                },
                "accountDescription": {
                  "type": "string"
                },
                "bankOwnAccountType": {
                  "type": "number",
                  "enum": [
                    1,
                    2,
                    3
                  ],
                  "nullable": true
                }
              }
            }
          },
          "vatAccountNumber": {
            "type": "string",
            "description": "Numer rachunku VAT (split payment / MPP)."
          },
          "vatAccountBank": {
            "type": "string",
            "description": "Nazwa banku rachunku VAT."
          },
          "vatAccountSwift": {
            "type": "string",
            "description": "SWIFT rachunku VAT."
          },
          "vatAccountDescription": {
            "type": "string",
            "description": "Opis rachunku VAT."
          },
          "paymentMethodId": {
            "type": "integer",
            "enum": [
              1,
              2,
              3,
              4,
              5,
              6,
              7
            ],
            "description": "Id metody płatności: 1=Gotówka, 2=Karta, 3=Bon, 4=Czek, 5=Kredyt, 6=Przelew, 7=Płatność mobilna",
            "example": 6
          },
          "paymentStatusId": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "0=Zapłacono (wymaga additionalPaymentDate albo partialPayments), 1=Do zapłaty (wymaga paymentDeadlineDate)",
            "example": 1
          },
          "partialPayments": {
            "type": "array",
            "maxItems": 100,
            "description": "Zapłaty częściowe dokonane do dnia wystawienia (KSeF ZaplataCzesciowa). Przy paymentStatusId=1 ich suma musi być mniejsza niż kwota do zapłaty. Przy paymentStatusId=0 co najmniej dwie wpłaty o sumie równej kwocie do zapłaty. Data wpłaty nie może być późniejsza niż data wystawienia.",
            "items": {
              "type": "object",
              "required": [
                "amount",
                "date"
              ],
              "properties": {
                "amount": {
                  "type": "number",
                  "example": 500
                },
                "date": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-09-14"
                },
                "paymentMethodId": {
                  "type": "integer",
                  "enum": [
                    1,
                    2,
                    3,
                    4,
                    5,
                    6,
                    7
                  ],
                  "nullable": true,
                  "description": "Forma wpłaty jak paymentMethodId; brak = nie podano",
                  "example": 1
                }
              }
            }
          },
          "annotations": {
            "$ref": "#/components/schemas/AnnotationsInput"
          },
          "additionalInfo": {
            "$ref": "#/components/schemas/AdditionalInfoInput"
          },
          "linkedOrderId": {
            "type": "string",
            "description": "ID zamówienia (wymagane dla FakturaZaliczka)"
          },
          "advancePaymentAmount": {
            "type": "number",
            "minimum": 0.01,
            "description": "Kwota zaliczki (wymagane dla FakturaZaliczka)"
          },
          "correctedInvoiceId": {
            "type": "string",
            "description": "ID faktury korygowanej (wymagane dla FakturaKorygujaca, FakturaKorygujacaZaliczkowa i FakturaKorygujacaRozliczeniowa). Gdy nie podasz nabywcy, odbiorcy, waluty albo adnotacji, korekta przejmuje je z tej faktury."
          },
          "correctionReason": {
            "type": "string",
            "maxLength": 256,
            "description": "Przyczyna korekty: opis, który trafia na PDF i do KSeF (PrzyczynaKorekty). Opcjonalna, najwyżej 256 znaków (limit KSeF)."
          },
          "correctionCause": {
            "type": "string",
            "nullable": true,
            "enum": [
              "after_sale",
              "mistake",
              null
            ],
            "example": "after_sale",
            "description": "Powód korekty: after_sale (zdarzenie po sprzedaży: rabat, zwrot towaru, reklamacja, cena albo ilość zmieniona po sprzedaży) albo mistake (błąd na fakturze korygowanej). Ustala TypKorekty wysyłany do KSeF, gdy nie podasz correctionType, i okres, w którym korekta wchodzi do raportów VAT i KPiR. Bez powodu korekta trafia do KSeF z TypKorekty 2, jak dotąd. Dotyczy tylko faktur korygujących, przy innych typach pole jest pomijane."
          },
          "correctionType": {
            "type": "integer",
            "nullable": true,
            "enum": [
              1,
              2,
              3,
              null
            ],
            "example": 1,
            "description": "TypKorekty w KSeF ustawiony ręcznie: 1 = skutek w dacie ujęcia faktury pierwotnej, 2 = w dacie wystawienia faktury korygującej, 3 = w innej dacie. Pomiń, a Fakturnia wyliczy go przy wysyłce: after_sale albo brak powodu daje 2, mistake daje 1, gdy korekta podnosi kwoty, ich nie zmienia albo zeruje całą fakturę (zły nabywca, duplikat), 2, gdy je obniża, i 3, gdy jedną stawkę podnosi, a inną obniża. Dotyczy tylko faktur korygujących."
          },
          "correctionEffectDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Faktury korygujące: dzień, od którego korekta działa w VAT, gdy nie jest to ani data faktury korygowanej, ani data korekty. Przy zwiększeniu po sprzedaży (after_sale) to dzień powstania przyczyny, np. uzgodnienia podwyżki (art. 29a ust. 17); z innego miesiąca niż korekta daje TypKorekty 3. Przy ręcznym correctionType=3 to dzień skutku. KSeF nie ma na nią pola; raport VAT i JPK ujmują korektę w tym dniu."
          },
          "correctionConfirmationDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Faktury korygujące zmniejszające wystawione poza KSeF: dzień otrzymania potwierdzenia odbioru korekty przez nabywcę. Według art. 29a ust. 13a obniżka wchodzi do rozliczenia za okres, w którym przyszło potwierdzenie, i tak ujmuje ją raport VAT."
          },
          "linkedAdvanceInvoiceIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "ID faktur zaliczkowych do rozliczenia (wymagane dla FakturaRozliczeniowa)"
          },
          "prepaymentIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "settlementAmount": {
            "type": "number",
            "description": "Kwota rozliczenia (FakturaRozliczeniowa). Wartość przekazywana bez automatycznych wyliczeń."
          },
          "isSettlementAmountManual": {
            "type": "boolean",
            "description": "Czy settlementAmount podano ręcznie."
          },
          "correctionAdvanceAmountAfter": {
            "type": "number",
            "description": "Kwota zaliczki PO korekcie (FakturaKorygujacaZaliczkowa)."
          },
          "correctionSettlementAmountAfter": {
            "type": "number",
            "description": "Kwota rozliczenia PO korekcie (FakturaKorygujacaRozliczeniowa)."
          },
          "signatures": {
            "type": "object",
            "description": "Podpisy na PDF (osoba uprawniona do wystawienia/odbioru).",
            "properties": {
              "issuerSignature": {
                "type": "object",
                "properties": {
                  "show": {
                    "type": "boolean"
                  },
                  "value": {
                    "type": "string"
                  }
                }
              },
              "receiverSignature": {
                "type": "object",
                "properties": {
                  "show": {
                    "type": "boolean"
                  },
                  "value": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "ksefJst": {
            "type": "boolean",
            "description": "Czy dokument jest dla JST (jednostki samorządu terytorialnego)"
          }
        }
      },
      "ValidatePreviewResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "preview": {
                    "type": "object",
                    "properties": {
                      "documentNo": {
                        "type": "integer",
                        "example": 1
                      },
                      "documentNumber": {
                        "type": "string",
                        "example": "FV/1/05/2026"
                      },
                      "symbol": {
                        "type": "string",
                        "example": "FV/"
                      },
                      "numberingFormat": {
                        "type": "string",
                        "example": "/MM/YYYY"
                      },
                      "seller": {
                        "$ref": "#/components/schemas/CompanyExternal"
                      },
                      "buyer": {
                        "$ref": "#/components/schemas/CompanyExternal"
                      },
                      "receiver": {
                        "nullable": true,
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/CompanyExternal"
                          }
                        ],
                        "description": "Odbiorca (Podmiot3); null, gdy dokument nie ma odbiorcy."
                      },
                      "hasReceiver": {
                        "type": "boolean",
                        "example": false
                      },
                      "totals": {
                        "type": "object",
                        "properties": {
                          "netSum": {
                            "type": "number",
                            "example": 100,
                            "description": "Suma netto pozycji. Pozycja w procedurze marży (vatRate \"marza\") nie ma netto i liczy się tu kwotą brutto: netto zwykłych stawek to netSum − marginSaleSum."
                          },
                          "vatSum": {
                            "type": "number",
                            "example": 23
                          },
                          "grossSum": {
                            "type": "number",
                            "example": 123
                          },
                          "marginSaleSum": {
                            "type": "number",
                            "example": 0,
                            "description": "Sprzedaż w procedurze marży zawarta w netSum (KSeF P_13_11, brutto, bez VAT na fakturze); 0 bez pozycji \"marza\"."
                          }
                        }
                      },
                      "receivedPayment": {
                        "type": "string",
                        "example": "NOT_RECEIVED"
                      },
                      "bankAccount": {
                        "type": "object",
                        "nullable": true,
                        "description": "Rachunek sprzedawcy, który zostanie wydrukowany na dokumencie (domyślny rachunek dla przelewu); null, gdy nie dotyczy.",
                        "properties": {
                          "accountNumber": {
                            "type": "string",
                            "example": "61 1090 1014 0000 0712 1981 2874"
                          },
                          "bank": {
                            "type": "string",
                            "example": "mBank"
                          }
                        }
                      },
                      "paymentInstallments": {
                        "type": "array",
                        "nullable": true,
                        "description": "Raty, które zostaną zapisane: przesłane w paymentInstallments albo wyliczone z paymentInstallmentsSplit; null przy jednym terminie płatności.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "date": {
                              "type": "string",
                              "format": "date",
                              "example": "2026-10-21"
                            },
                            "amount": {
                              "type": "number",
                              "example": 410
                            }
                          }
                        }
                      },
                      "warnings": {
                        "type": "array",
                        "description": "Uwagi, które nie blokują dokumentu; pokaż je użytkownikowi. Korekta, której faktura pierwotna nie ma numeru KSeF (na kontach połączonych z KSeF), dostaje jedną z nich: CORRECTION_ORIGINAL_KSEF_PENDING (faktura pierwotna czeka na numer KSeF), CORRECTION_ORIGINAL_NOT_SENT_TO_KSEF (faktura pierwotna jest z dzisiaj i nie została wysłana: wyślij ją najpierw) albo CORRECTION_ORIGINAL_OUTSIDE_KSEF (faktury pierwotnej nie da się już wysłać do KSeF). Bez numeru korekta trafia do KSeF jako korekta faktury wystawionej poza KSeF. Pusta lista, gdy nie ma uwag.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "code": {
                              "type": "string",
                              "example": "CORRECTION_ORIGINAL_NOT_SENT_TO_KSEF"
                            },
                            "message": {
                              "type": "string",
                              "example": "Faktura FV/1/10/2026 nie została wysłana do KSeF. Wyślij najpierw fakturę, a potem korektę."
                            }
                          }
                        },
                        "example": []
                      }
                    }
                  },
                  "valid": {
                    "type": "boolean",
                    "example": true
                  },
                  "warnings": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/PartyIdentifierWarning"
                    },
                    "description": "Jak odczytano identyfikatory kontrahenta (pusta lista, gdy podano je jawnie i poprawnie)."
                  }
                }
              }
            }
          }
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "description": "Koperta błędu. `message` to stały kod (na nim rozgałęziaj logikę), `errors` zawiera szczegóły: obiekty per pole albo zdania wyjaśniające.",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "data": {
            "type": "object",
            "nullable": true,
            "example": null
          },
          "message": {
            "type": "string",
            "nullable": true,
            "example": "VALIDATION_ERROR",
            "description": "Kod błędu, np. VALIDATION_ERROR, NOT_FOUND, SUBSCRIPTION_REQUIRED."
          },
          "executionTime": {
            "type": "number",
            "nullable": true,
            "example": 50
          },
          "errors": {
            "type": "array",
            "nullable": true,
            "items": {
              "oneOf": [
                {
                  "type": "string",
                  "description": "Zdanie wyjaśniające (błędy bez pola)."
                },
                {
                  "type": "object",
                  "description": "Błąd przypisany do pola.",
                  "properties": {
                    "field": {
                      "type": "string",
                      "nullable": true
                    },
                    "code": {
                      "type": "string",
                      "nullable": true
                    },
                    "message": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              ]
            },
            "example": [
              {
                "field": "documentType",
                "code": "REQUIRED",
                "message": "documentType jest wymagany."
              }
            ]
          }
        },
        "required": [
          "success",
          "data",
          "message"
        ]
      },
      "SuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "object",
            "example": null
          },
          "message": {
            "type": "string",
            "nullable": true,
            "example": "OPERATION_SUCCESSFUL"
          },
          "executionTime": {
            "type": "number",
            "nullable": true,
            "example": 50
          }
        },
        "required": [
          "success",
          "data"
        ]
      },
      "DocumentSuccessResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "document": {
                    "$ref": "#/components/schemas/DocumentExternal"
                  },
                  "warnings": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/PartyIdentifierWarning"
                    },
                    "description": "Jak odczytano identyfikatory kontrahenta (pusta lista, gdy podano je jawnie i poprawnie)."
                  }
                }
              }
            }
          }
        ]
      },
      "DictionariesResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "documentTypes": {
                    "type": "array",
                    "description": "Typy obsługiwane przez External API (bez typów zaszłościowych).",
                    "items": {
                      "type": "string"
                    },
                    "example": [
                      "FakturaVAT",
                      "FakturaKorygujaca"
                    ]
                  },
                  "paymentMethods": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "example": "Przelew"
                        },
                        "paymentMethodId": {
                          "type": "integer",
                          "example": 6
                        }
                      }
                    }
                  },
                  "paymentStatuses": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 1
                        },
                        "name": {
                          "type": "string",
                          "example": "Do zapłaty"
                        }
                      }
                    }
                  },
                  "marginProcedures": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 1
                        },
                        "text": {
                          "type": "string",
                          "example": "Procedura marży dla biur podróży"
                        }
                      }
                    }
                  },
                  "vatExemptionTypes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "example": "A"
                        },
                        "label": {
                          "type": "string"
                        },
                        "placeholder": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "gtu": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "example": "GTU_01"
                        },
                        "description": {
                          "type": "string",
                          "example": "Dostawa napojów alkoholowych"
                        }
                      }
                    }
                  },
                  "vatRates": {
                    "type": "array",
                    "description": "Stawki VAT, wartość na druku (value), etykieta (label) i opis. 0% KR/WDT/EX to różne stawki.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "value": {
                          "oneOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "string"
                            }
                          ],
                          "example": "0 KR"
                        },
                        "label": {
                          "type": "string",
                          "example": "0% - KR"
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    },
                    "example": [
                      {
                        "value": 23,
                        "label": "23%"
                      },
                      {
                        "value": "zw",
                        "label": "zw.",
                        "description": "Zwolnione od podatku"
                      },
                      {
                        "value": "0 WDT",
                        "label": "0% - WDT",
                        "description": "0% w przypadku wewnątrzwspólnotowej dostawy towarów (WDT)"
                      }
                    ]
                  },
                  "currencies": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "example": "PLN"
                        },
                        "name": {
                          "type": "string",
                          "example": "Złoty polski"
                        },
                        "availableExchangeRate": {
                          "type": "boolean",
                          "example": false
                        }
                      }
                    }
                  },
                  "countries": {
                    "type": "array",
                    "description": "Kody krajów (ISO 3166-1 alpha-2) i nazwy. Do dokumentu wysyłaj countryCode.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "PL"
                        },
                        "name": {
                          "type": "string",
                          "example": "Polska"
                        }
                      }
                    }
                  },
                  "paymentDateHeaders": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 0
                        },
                        "name": {
                          "type": "string",
                          "example": "Data płatności"
                        }
                      }
                    }
                  },
                  "additionalDateHeaders": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "example": 0
                        },
                        "name": {
                          "type": "string",
                          "example": "Data sprzedaży"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "DocumentExternal": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "userId": {
            "type": "string",
            "nullable": true
          },
          "documentNumber": {
            "type": "string",
            "nullable": true,
            "example": "FV/1/05/2026"
          },
          "documentNo": {
            "type": "integer",
            "nullable": true,
            "example": 1
          },
          "symbol": {
            "type": "string",
            "nullable": true,
            "example": "FV/"
          },
          "documentType": {
            "type": "string",
            "nullable": true,
            "example": "FakturaVAT"
          },
          "source": {
            "type": "string",
            "enum": [
              "local",
              "ksef"
            ],
            "example": "local",
            "description": "local = wystawiony w Fakturni (aplikacja, API, MCP, reguła cykliczna); ksef = pobrany z KSeF (zdarzenie document.ksefImported)."
          },
          "direction": {
            "type": "string",
            "enum": [
              "income",
              "expense",
              "order"
            ],
            "example": "income",
            "description": "income = sprzedaż, expense = zakup (np. faktura od dostawcy pobrana z KSeF), order = zamówienie albo oferta."
          },
          "issueDate": {
            "type": "string",
            "nullable": true,
            "example": "2026-05-07"
          },
          "issuePlace": {
            "type": "string",
            "nullable": true,
            "example": "Warszawa"
          },
          "subDate": {
            "type": "string",
            "nullable": true
          },
          "subDateTo": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Koniec okresu sprzedaży (KSeF OkresFa P_6_Do); null przy jednej dacie sprzedaży."
          },
          "subDateHeader": {
            "type": "string",
            "nullable": true
          },
          "additionalPaymentDate": {
            "type": "string",
            "nullable": true
          },
          "additionalPaymentDateHeader": {
            "type": "string",
            "nullable": true
          },
          "paymentDeadlineDate": {
            "type": "string",
            "nullable": true,
            "example": "2026-05-14"
          },
          "buyer": {
            "$ref": "#/components/schemas/CompanyExternal"
          },
          "seller": {
            "$ref": "#/components/schemas/CompanyExternal"
          },
          "receiver": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/CompanyExternal"
              }
            ],
            "description": "Odbiorca (Podmiot3); null, gdy dokument nie ma odbiorcy."
          },
          "grossSum": {
            "type": "number",
            "nullable": true,
            "example": 123
          },
          "currency": {
            "type": "string",
            "nullable": true,
            "example": "PLN"
          },
          "exchangeRate": {
            "type": "number",
            "nullable": true
          },
          "exchangeRateDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Dzień tabeli NBP kursu exchangeRate (art. 31a ustawy o VAT)."
          },
          "exchangeRateTable": {
            "type": "string",
            "nullable": true,
            "description": "Numer tabeli NBP kursu exchangeRate."
          },
          "taxPointRule": {
            "type": "string",
            "nullable": true,
            "enum": [
              "art19a5p3a",
              "art19a5p3b",
              "art19a5p3c",
              "art19a5p4",
              null
            ],
            "description": "Obowiązek podatkowy z datą wystawienia faktury (art. 19a ust. 5 pkt 3 i 4); null = zwykłe zasady."
          },
          "paymentInstallments": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date"
                },
                "amount": {
                  "type": "number"
                }
              }
            },
            "description": "Raty (KSeF TerminPlatnosci); [] = jeden termin płatności."
          },
          "paymentDeadlineTerm": {
            "type": "object",
            "nullable": true,
            "properties": {
              "count": {
                "type": "integer"
              },
              "unit": {
                "type": "string",
                "enum": [
                  "day",
                  "week",
                  "month"
                ]
              },
              "event": {
                "type": "string",
                "enum": [
                  "issue",
                  "invoice_delivery",
                  "supply",
                  "acceptance"
                ]
              }
            },
            "description": "Termin płatności opisany słowami (KSeF TerminOpis)."
          },
          "advanceReceipts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date"
                },
                "amount": {
                  "type": "number"
                },
                "exchangeRate": {
                  "type": "number",
                  "nullable": true
                },
                "exchangeRateDate": {
                  "type": "string",
                  "format": "date",
                  "nullable": true
                }
              }
            },
            "description": "Kilka wpłat na fakturze zaliczkowej (KSeF ZaliczkaCzesciowa); [] = jedna data otrzymania."
          },
          "prepaymentIds": {
            "type": "array",
            "nullable": true
          },
          "correctedInvoiceId": {
            "type": "string",
            "nullable": true
          },
          "externalSource": {
            "type": "string",
            "nullable": true,
            "example": "woocommerce",
            "description": "Identyfikator systemu źródłowego (np. woocommerce, shopify, erp)."
          },
          "externalOrderId": {
            "type": "string",
            "nullable": true,
            "example": "10234",
            "description": "Identyfikator zamówienia w systemie źródłowym."
          },
          "externalOrderNumber": {
            "type": "string",
            "nullable": true,
            "example": "#10234",
            "description": "Numer zamówienia widoczny dla użytkownika (opcjonalny)."
          },
          "products": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string",
                  "example": "Usługa programistyczna"
                },
                "gtu": {
                  "type": "string",
                  "nullable": true
                },
                "unitOfMeasure": {
                  "type": "string",
                  "example": "szt."
                },
                "discount": {
                  "type": "number",
                  "example": 0
                },
                "quantity": {
                  "type": "number",
                  "example": 1
                },
                "netPrice": {
                  "type": "number",
                  "example": 100
                },
                "netValue": {
                  "type": "number",
                  "example": 100
                },
                "grossValue": {
                  "type": "number",
                  "example": 123
                },
                "amountOfVat": {
                  "type": "number",
                  "example": 23
                },
                "vatRate": {
                  "oneOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "string"
                    }
                  ],
                  "example": 23,
                  "description": "Liczba albo kod specjalny (zw, np I, oo, 0 KR, 0 WDT, 0 EX, marza)."
                },
                "taxSymbol": {
                  "type": "string",
                  "nullable": true,
                  "example": "%"
                },
                "pkwiu": {
                  "type": "string",
                  "nullable": true
                },
                "marginPurchaseValue": {
                  "type": "number",
                  "nullable": true,
                  "description": "Tylko vatRate \"marza\": kwota nabycia pozycji w PLN (dane sprzedawcy, nie na fakturze)."
                },
                "marginTaxRate": {
                  "type": "number",
                  "nullable": true,
                  "description": "Tylko vatRate \"marza\": stawka VAT od marży (23, 8, 5, 0)."
                }
              }
            }
          },
          "payment": {
            "type": "object",
            "nullable": true,
            "properties": {
              "method": {
                "type": "integer",
                "nullable": true,
                "description": "KSeF FormaPlatnosci: 1=Gotówka, 2=Karta, 3=Bon, 4=Czek, 5=Kredyt, 6=Przelew, 7=Płatność mobilna",
                "example": 6
              },
              "status": {
                "type": "integer",
                "nullable": true,
                "description": "0=Zapłacono, 1=Do zapłaty",
                "example": 1
              },
              "bankAccountNumber": {
                "type": "string",
                "nullable": true,
                "example": "1212 1212 1212 1212 1212 1212"
              },
              "partialPayments": {
                "type": "array",
                "description": "Zapłaty częściowe dokonane do dnia wystawienia (KSeF ZaplataCzesciowa); pusta lista, gdy ich nie ma",
                "items": {
                  "type": "object",
                  "properties": {
                    "amount": {
                      "type": "number",
                      "example": 500
                    },
                    "date": {
                      "type": "string",
                      "format": "date",
                      "example": "2026-09-14"
                    },
                    "paymentMethodId": {
                      "type": "integer",
                      "nullable": true,
                      "description": "KSeF FormaPlatnosci 1-7; null = nie podano",
                      "example": 1
                    }
                  }
                }
              },
              "paidAmount": {
                "type": "number",
                "nullable": true,
                "description": "Kwota zapłacona według treści faktury: całość przy status=0, suma zapłat częściowych przy status=1",
                "example": 500
              },
              "amountDue": {
                "type": "number",
                "nullable": true,
                "description": "Kwota pozostała do zapłaty według treści faktury (bez wpłat zarejestrowanych po wystawieniu)",
                "example": 730
              },
              "receivedPayment": {
                "type": "string",
                "enum": [
                  "RECEIVED",
                  "NOT_RECEIVED"
                ],
                "description": "Rozrachunek zarejestrowany po wystawieniu (PATCH /documents/{id}/payment-status albo „Otrzymano płatność\" w aplikacji), niezależny od treści faktury",
                "example": "NOT_RECEIVED"
              },
              "receivedPaymentAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Kiedy zarejestrowano otrzymanie płatności (null, gdy nie zarejestrowano)",
                "example": null
              },
              "receivedPaymentDate": {
                "type": "string",
                "format": "date",
                "nullable": true,
                "description": "Dzień, w którym wpłata wpłynęła, podany przy oznaczaniu zapłaty (dla metody kasowej to dzień obowiązku podatkowego); null, gdy nie podano",
                "example": null
              },
              "settled": {
                "type": "boolean",
                "nullable": true,
                "description": "Czy dokument jest rozliczony: status „Zapłacono\" albo zarejestrowana wpłata (receivedPayment=RECEIVED); null dla dokumentów bez statusu płatności",
                "example": false
              },
              "outstandingAmount": {
                "type": "number",
                "nullable": true,
                "description": "Kwota, która pozostaje do zapłaty dziś: 0 dla dokumentu rozliczonego, inaczej amountDue",
                "example": 730
              }
            }
          },
          "comments": {
            "type": "string",
            "nullable": true
          },
          "marginProcedureId": {
            "type": "integer",
            "nullable": true
          },
          "vatAccountNumber": {
            "type": "string",
            "nullable": true
          },
          "netSum": {
            "type": "number",
            "nullable": true,
            "example": 100,
            "description": "Suma netto pozycji. Pozycja w procedurze marży (vatRate \"marza\") nie ma netto i liczy się tu kwotą brutto (KSeF wykazuje ją osobno, w P_13_11): netto zwykłych stawek to netSum minus brutto pozycji \"marza\"."
          },
          "vatSum": {
            "type": "number",
            "nullable": true,
            "example": 23
          },
          "annotations": {
            "type": "object",
            "nullable": true,
            "description": "Adnotacje KSeF dokumentu (MPP, odwrotne obciążenie, metoda kasowa, samofakturowanie, procedura marży, zwolnienie z VAT); null, gdy brak.",
            "properties": {
              "isSplitPayment": {
                "type": "boolean"
              },
              "isReverseCharge": {
                "type": "boolean"
              },
              "isCashMethod": {
                "type": "boolean"
              },
              "isSelfInvoicing": {
                "type": "boolean"
              },
              "marginProcedure": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "procedureId": {
                    "type": "integer",
                    "nullable": true
                  }
                }
              },
              "vatExemption": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "exemptionType": {
                    "type": "string",
                    "nullable": true
                  },
                  "legalBasis": {
                    "type": "string",
                    "nullable": true
                  },
                  "showOnDocument": {
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "additionalInfo": {
            "type": "object",
            "nullable": true,
            "properties": {
              "isInvoiceToReceipt": {
                "type": "boolean"
              }
            }
          },
          "correctionReason": {
            "type": "string",
            "nullable": true,
            "description": "Korekty: przyczyna drukowana na PDF i wysyłana do KSeF (PrzyczynaKorekty)."
          },
          "correctionCause": {
            "type": "string",
            "nullable": true,
            "enum": [
              "after_sale",
              "mistake",
              null
            ],
            "example": "after_sale",
            "description": "Korekty: powód wystawienia korekty. after_sale = zdarzenie po sprzedaży (rabat, zwrot, reklamacja, cena albo ilość zmieniona później), mistake = błąd na fakturze korygowanej. null, gdy nie podano."
          },
          "correctionType": {
            "type": "integer",
            "nullable": true,
            "enum": [
              1,
              2,
              3,
              null
            ],
            "example": null,
            "description": "Korekty: TypKorekty w KSeF ustawiony ręcznie (1 = skutek w dacie faktury korygowanej, 2 = w dacie wystawienia korekty, 3 = w innej dacie). null = wyliczany z correctionCause i kwot przy wysyłce korekty do KSeF."
          },
          "correctionEffectDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Faktury korygujące: dzień, od którego korekta działa (przyczyna zwiększenia, art. 29a ust. 17, albo ręczny TypKorekty 3)."
          },
          "correctionConfirmationDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Korekty wystawione poza KSeF: dzień potwierdzenia przez nabywcę odbioru korekty zmniejszającej (art. 29a ust. 13a)."
          },
          "isDraft": {
            "type": "boolean",
            "description": "Szkic zapisany w aplikacji, jeszcze niewystawiony. Wystawienie ustawia false i wysyła webhook document.updated.",
            "example": false
          },
          "correctionAdvanceAmountAfter": {
            "type": "number",
            "nullable": true,
            "description": "Korekta zaliczkowa: kwota zaliczki po korekcie."
          },
          "correctionSettlementAmountAfter": {
            "type": "number",
            "nullable": true,
            "description": "Korekta rozliczeniowa: kwota rozliczenia po korekcie."
          },
          "invoiceName": {
            "type": "string",
            "nullable": true,
            "example": "Faktura zaliczkowa",
            "description": "Nazwa faktury (np. dla FV zaliczkowych)"
          },
          "isCorrected": {
            "type": "boolean",
            "description": "Do dokumentu wystawiono korektę: edycja i usuwanie są zablokowane.",
            "example": false
          },
          "linkedOrderId": {
            "type": "string",
            "nullable": true,
            "description": "FakturaZaliczka: zamówienie, którego dotyczy zaliczka."
          },
          "advancePaymentAmount": {
            "type": "number",
            "nullable": true
          },
          "linkedAdvanceInvoiceIds": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            },
            "description": "FakturaRozliczeniowa: rozliczone faktury zaliczkowe."
          },
          "linkedDocuments": {
            "type": "array",
            "description": "Dokumenty powiązane: wz_to_invoice (WZ wystawiony do tej faktury), invoice_to_wz (faktura tego WZ), correction, order_to_invoice, prepayment.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "relation": {
                  "type": "string",
                  "enum": [
                    "correction",
                    "wz_to_invoice",
                    "order_to_invoice",
                    "prepayment",
                    "invoice_to_wz"
                  ]
                },
                "documentNumber": {
                  "type": "string",
                  "nullable": true,
                  "example": "WZ1/09/2026"
                }
              }
            }
          },
          "settlementAmount": {
            "type": "number",
            "nullable": true,
            "description": "FakturaRozliczeniowa: kwota pozostała do zapłaty po odjęciu zaliczek."
          },
          "warehouseId": {
            "type": "string",
            "nullable": true
          },
          "warehouseName": {
            "type": "string",
            "nullable": true
          },
          "sourceWarehouseId": {
            "type": "string",
            "nullable": true
          },
          "targetWarehouseId": {
            "type": "string",
            "nullable": true
          },
          "stockStatus": {
            "type": "string",
            "nullable": true,
            "description": "Dokumenty magazynowe: zaksięgowany albo oczekujący."
          },
          "isSent": {
            "type": "boolean",
            "example": false
          },
          "isDownloaded": {
            "type": "boolean",
            "example": false
          },
          "isPrinted": {
            "type": "boolean",
            "example": false
          },
          "hasReceiver": {
            "type": "boolean",
            "example": false
          },
          "hasComments": {
            "type": "boolean",
            "example": false
          },
          "hasGTU": {
            "type": "boolean",
            "example": false
          },
          "hasDiscount": {
            "type": "boolean",
            "example": false
          },
          "hasPaymentDescription": {
            "type": "boolean",
            "example": false
          },
          "ksefNumber": {
            "type": "string",
            "nullable": true,
            "example": "5271012345-20260926-AABBCCDDEEFF-01"
          },
          "ksefReferenceNumber": {
            "type": "string",
            "nullable": true
          },
          "ksefStatus": {
            "type": "object",
            "nullable": true,
            "description": "Ostatni status z KSeF.",
            "properties": {
              "code": {
                "type": "integer",
                "example": 200
              },
              "description": {
                "type": "string",
                "example": "Przyjęto"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "example": []
              }
            }
          },
          "ksefSent": {
            "type": "boolean",
            "example": false
          },
          "signatures": {
            "type": "object",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "example": "2026-05-07T10:30:00.000Z"
          },
          "updatedAt": {
            "type": "string",
            "example": "2026-05-07T10:30:00.000Z"
          }
        }
      },
      "CompanyExternal": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true,
            "example": "company"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "example": "Acme Corp Sp. z o.o."
          },
          "nip": {
            "type": "string",
            "nullable": true,
            "example": "5261040828"
          },
          "vatUE": {
            "type": "string",
            "nullable": true
          },
          "regon": {
            "type": "string",
            "nullable": true
          },
          "krs": {
            "type": "string",
            "nullable": true
          },
          "bdo": {
            "type": "string",
            "nullable": true
          },
          "pesel": {
            "type": "string",
            "nullable": true,
            "description": "PESEL. U sprzedawcy zwracany tylko wtedy, gdy dokument go drukuje (fieldsToShow zawiera pesel)."
          },
          "idNumber": {
            "type": "string",
            "nullable": true,
            "description": "Numer dowodu osobistego. U sprzedawcy zwracany tylko wtedy, gdy dokument go drukuje (fieldsToShow zawiera idNumber)."
          },
          "street": {
            "type": "string",
            "nullable": true,
            "example": "Marszałkowska 1"
          },
          "postalCode": {
            "type": "string",
            "nullable": true,
            "example": "00-001"
          },
          "city": {
            "type": "string",
            "nullable": true,
            "example": "Warszawa"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "example": "Polska"
          },
          "countryCode": {
            "type": "string",
            "nullable": true,
            "example": "PL"
          },
          "phoneNumber": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "www": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "ClientReference": {
        "type": "object",
        "description": "Kontrahent podany danymi (nabywca albo odbiorca). Zapisany kontrahent z tym NIP-em albo numerem VAT UE jest użyty z kartoteki; nowy zostaje dodany do kontrahentów.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "company",
              "person"
            ]
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "nip": {
            "type": "string",
            "nullable": true,
            "example": "5261040828",
            "description": "Polski NIP (identifierType=nip): 10 cyfr; spacje, myślniki i prefiks PL są usuwane, sprawdzana jest cyfra kontrolna. Nie wpisuj tu zagranicznego numeru VAT: numer VAT UE podaj w vatUE."
          },
          "vatUE": {
            "type": "string",
            "nullable": true,
            "example": "DE123456789",
            "description": "Numer VAT UE z prefiksem kraju, np. DE123456789, ATU12345678, EL123456789 (Grecja). Zapisywany wielkimi literami, bez spacji; numer bez prefiksu dostaje prefiks z countryCode. Polska firma z identifierType=nip może mieć tu numer PL i ten sam NIP (WDT)."
          },
          "pesel": {
            "type": "string",
            "nullable": true
          },
          "regon": {
            "type": "string",
            "nullable": true
          },
          "krs": {
            "type": "string",
            "nullable": true
          },
          "bdo": {
            "type": "string",
            "nullable": true
          },
          "identifierType": {
            "type": "string",
            "nullable": true,
            "enum": [
              "nip",
              "vatEu",
              "other",
              "idWew",
              "none",
              null
            ],
            "example": "nip",
            "description": "Który identyfikator wskazuje kontrahenta w KSeF. nip: polska firma, nip = 10 cyfr, np. 5261040828 (spacje, myślniki i prefiks PL są usuwane, sprawdzana jest cyfra kontrolna). vatEu: kontrahent z UE, numer VAT UE z prefiksem kraju w vatUE, np. kontrahent z Niemiec: identifierType=vatEu, vatUE=DE123456789 (Grecja ma prefiks EL; Irlandia Północna XI nie jest krajem UE w KSeF, podaj ją jako other). other: kontrahent spoza UE (albo z UE bez numeru VAT UE), kraj i identyfikator, np. identifierType=other, countryCode=US, otherTaxIdentifier=12-3456789. idWew: tylko odbiorca (receiver), jednostka wewnętrzna nabywcy, idWew=NIP-NNNNN; nabywca z idWew jest odrzucany. none: osoba prywatna albo brak identyfikatora. Bez identifierType serwer ustala typ z danych: polski NIP w nip to nip, numer VAT UE kraju UE (także wpisany w nip) to vatEu i trafia do vatUE, identyfikator kraju spoza UE to other, brak identyfikatora to none; ustalony typ i każde przeniesienie numeru zwraca w data.warnings. Podawaj identifierType jawnie. Sprzeczne dane: 422 PARTY_IDENTIFIER_INVALID z nazwą pola (np. buyer.vatUE). Nabywca podany przez buyerId jest brany z kartoteki bez zmian."
          },
          "otherTaxIdentifier": {
            "type": "string",
            "nullable": true,
            "description": "Identyfikator podatkowy przy identifierType=other (KSeF NrID), np. 12-3456789 dla firmy z USA; najwyżej 50 znaków, wymaga countryCode."
          },
          "idWew": {
            "type": "string",
            "nullable": true,
            "description": "Identyfikator wewnętrzny jednostki przy identifierType=idWew: NIP-NNNNN (10 cyfr NIP, myślnik, 5 cyfr), np. 5252248481-16006."
          },
          "street": {
            "type": "string",
            "nullable": true
          },
          "postalCode": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          },
          "countryCode": {
            "type": "string",
            "nullable": true,
            "description": "Kod kraju ISO 3166-1 alpha-2, np. PL, DE, GR. Przy vatEu bez countryCode przyjmowany z prefiksu numeru VAT UE."
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "phoneNumber": {
            "type": "string",
            "nullable": true
          },
          "www": {
            "type": "string",
            "nullable": true
          },
          "fieldsToShow": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        }
      },
      "AnnotationsInput": {
        "type": "object",
        "properties": {
          "isSplitPayment": {
            "type": "boolean",
            "description": "MPP - split payment. Wyklucza się z isCashMethod.",
            "example": false
          },
          "isReverseCharge": {
            "type": "boolean",
            "description": "Odwrotne obciążenie"
          },
          "isCashMethod": {
            "type": "boolean",
            "description": "Metoda kasowa. Wyklucza się z isSplitPayment.",
            "example": false
          },
          "isSelfInvoicing": {
            "type": "boolean",
            "description": "Samofakturowanie"
          },
          "marginProcedure": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean",
                "example": true
              },
              "procedureId": {
                "type": "integer",
                "minimum": 1,
                "maximum": 4,
                "description": "ID procedury marży (1-4): 1 biura podróży, 2 towary używane, 3 dzieła sztuki, 4 przedmioty kolekcjonerskie i antyki",
                "example": 2
              }
            }
          },
          "vatExemption": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean",
                "example": false
              },
              "exemptionType": {
                "type": "string",
                "enum": [
                  "A",
                  "B",
                  "C"
                ]
              },
              "legalBasis": {
                "type": "string"
              },
              "showOnDocument": {
                "type": "boolean",
                "example": false
              }
            }
          }
        }
      },
      "AdditionalInfoInput": {
        "type": "object",
        "description": "Informacje dodatkowe dokumentu — sekcja KSeF FA(3) „Informacje dodatkowe” (osobna od adnotacji).",
        "properties": {
          "isInvoiceToReceipt": {
            "type": "boolean",
            "description": "Faktura do paragonu (art. 109 ust. 3d ustawy o VAT). Gdy `true`, w wysyłce do KSeF zostaje ustawiona flaga `<FP>1</FP>`, a na PDF pojawia się stosowna adnotacja. RodzajFaktury pozostaje bez zmian (np. VAT).",
            "example": true
          }
        }
      },
      "DocumentListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "documents": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/DocumentExternal"
                    }
                  },
                  "currentPage": {
                    "type": "integer",
                    "example": 1,
                    "description": "Numer bieżącej strony (od 1)."
                  },
                  "totalPages": {
                    "type": "integer",
                    "example": 5,
                    "description": "Liczba stron."
                  },
                  "totalCount": {
                    "type": "integer",
                    "example": 50,
                    "description": "Liczba wszystkich pasujących rekordów."
                  },
                  "itemsPerPage": {
                    "type": "integer",
                    "example": 10,
                    "description": "Rozmiar strony (maks. 100)."
                  },
                  "searchQuery": {
                    "type": "string",
                    "example": "",
                    "description": "Użyty filtr tekstowy (pusty, gdy brak)."
                  }
                }
              }
            }
          }
        ]
      },
      "DeletedResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "681a3b2c4d5e6f7a8b9c0d1e",
                    "description": "Identyfikator usuniętego zasobu."
                  }
                }
              }
            }
          }
        ]
      },
      "DocumentHistoryEntry": {
        "type": "object",
        "description": "Wpis dziennika dokumentu.",
        "properties": {
          "id": {
            "type": "string",
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "type": {
            "type": "string",
            "example": "PAYMENT_RECEIVED",
            "description": "CREATE, UPDATE, DELETE, SENT_BY_EMAIL, DOWNLOAD, DOWNLOAD_XML, DOWNLOAD_UPO, PRINT, KSEF_SENT, KSEF_ERROR, PAYMENT_RECEIVED, PAYMENT_REVERTED, ADVANCE_INVOICE_LINKED, ADVANCE_INVOICE_UNLINKED, SETTLEMENT_INVOICE_LINKED, SETTLEMENT_INVOICE_UNLINKED, DOWNLOAD_CLIENT."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "actor": {
            "type": "string",
            "enum": [
              "owner",
              "employee"
            ],
            "example": "owner"
          },
          "employeeId": {
            "type": "string",
            "nullable": true
          },
          "employeeName": {
            "type": "string",
            "nullable": true
          },
          "origin": {
            "type": "string",
            "nullable": true,
            "enum": [
              "external_api",
              "app",
              "import",
              null
            ],
            "example": "external_api",
            "description": "Skąd przyszła akcja, gdy wpis to zapisuje."
          },
          "channel": {
            "type": "string",
            "nullable": true,
            "enum": [
              "mcp",
              null
            ],
            "example": "mcp",
            "description": "mcp, gdy akcję wykonał asystent AI przez serwer MCP."
          },
          "channelLabel": {
            "type": "string",
            "nullable": true,
            "example": "Claude",
            "description": "Nazwa poświadczenia asystenta (np. Claude, ChatGPT albo etykieta klucza)."
          },
          "changes": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Różnice pól przy UPDATE (pole, wartość przed i po)."
          },
          "data": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Szczegóły wpisu (np. wynik KSeF, adresaci e-maila)."
          }
        }
      },
      "DocumentHistoryResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "documentId": {
                    "type": "string",
                    "example": "681a3b2c4d5e6f7a8b9c0d1e"
                  },
                  "documentNumber": {
                    "type": "string",
                    "nullable": true,
                    "example": "FV/12/09/2026"
                  },
                  "entries": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/DocumentHistoryEntry"
                    }
                  },
                  "currentPage": {
                    "type": "integer",
                    "example": 1,
                    "description": "Numer bieżącej strony (od 1)."
                  },
                  "totalPages": {
                    "type": "integer",
                    "example": 5,
                    "description": "Liczba stron."
                  },
                  "totalCount": {
                    "type": "integer",
                    "example": 50,
                    "description": "Liczba wszystkich pasujących rekordów."
                  },
                  "itemsPerPage": {
                    "type": "integer",
                    "example": 10,
                    "description": "Rozmiar strony (maks. 100)."
                  },
                  "searchQuery": {
                    "type": "string",
                    "example": "",
                    "description": "Użyty filtr tekstowy (pusty, gdy brak)."
                  }
                }
              }
            }
          }
        ]
      },
      "PaymentStatusInput": {
        "type": "object",
        "required": [
          "receivedPayment"
        ],
        "properties": {
          "receivedPayment": {
            "type": "string",
            "enum": [
              "RECEIVED",
              "NOT_RECEIVED"
            ],
            "description": "RECEIVED oznacza dokument jako zapłacony, NOT_RECEIVED cofa oznaczenie."
          },
          "paymentDate": {
            "type": "string",
            "format": "date",
            "description": "Dzień, w którym wpłata wpłynęła (RRRR-MM-DD), tylko z RECEIVED. Domyślnie dzisiejszy dzień w Polsce; nie może być z przyszłości. Przy metodzie kasowej to dzień obowiązku podatkowego (art. 21 ust. 1 ustawy o VAT)."
          }
        }
      },
      "DocumentPaymentStatusResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "Document marked as paid."
              },
              "data": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "681a3b2c4d5e6f7a8b9c0d1e"
                  },
                  "receivedPayment": {
                    "type": "string",
                    "enum": [
                      "RECEIVED",
                      "NOT_RECEIVED"
                    ],
                    "example": "RECEIVED"
                  },
                  "receivedPaymentAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": "2026-09-26T10:30:00.000Z",
                    "description": "Moment oznaczenia zapłaty; null po cofnięciu."
                  },
                  "receivedPaymentDate": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "example": "2026-05-10",
                    "description": "Dzień wpłaty podany przy oznaczaniu (domyślnie dzień oznaczenia); null po cofnięciu."
                  }
                }
              }
            }
          }
        ]
      },
      "ExternalReferenceInput": {
        "type": "object",
        "required": [
          "externalSource",
          "externalOrderId"
        ],
        "properties": {
          "externalSource": {
            "type": "string",
            "example": "woocommerce",
            "description": "Identyfikator systemu źródłowego (np. woocommerce, shopify, erp)."
          },
          "externalOrderId": {
            "type": "string",
            "example": "10234",
            "description": "Identyfikator zamówienia w systemie źródłowym."
          },
          "externalOrderNumber": {
            "type": "string",
            "example": "#10234",
            "description": "Numer zamówienia widoczny dla użytkownika (opcjonalny)."
          }
        }
      },
      "MarginPurchasesInput": {
        "type": "object",
        "required": [
          "lines"
        ],
        "properties": {
          "lines": {
            "type": "array",
            "minItems": 1,
            "maxItems": 500,
            "items": {
              "type": "object",
              "required": [
                "index"
              ],
              "properties": {
                "index": {
                  "type": "integer",
                  "minimum": 0,
                  "example": 0,
                  "description": "Pozycja w products (od 0); musi mieć vatRate \"marza\"."
                },
                "marginPurchaseValue": {
                  "type": "number",
                  "nullable": true,
                  "minimum": 0,
                  "example": 1500,
                  "description": "Kwota nabycia całej pozycji brutto w PLN; null czyści, brak klucza zostawia."
                },
                "marginTaxRate": {
                  "type": "number",
                  "nullable": true,
                  "enum": [
                    23,
                    8,
                    5,
                    0,
                    null
                  ],
                  "example": 23,
                  "description": "Stawka VAT od marży; brak klucza zostawia, null = 23."
                }
              }
            }
          }
        }
      },
      "DocumentMarginPurchasesResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "Margin purchase amounts saved."
              },
              "data": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "681a3b2c4d5e6f7a8b9c0d1e"
                  },
                  "products": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "index": {
                          "type": "integer",
                          "example": 0
                        },
                        "marginPurchaseValue": {
                          "type": "number",
                          "nullable": true,
                          "example": 1500
                        },
                        "marginTaxRate": {
                          "type": "number",
                          "nullable": true,
                          "example": 23
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "DocumentExternalReferenceResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "External reference updated."
              },
              "data": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "681a3b2c4d5e6f7a8b9c0d1e"
                  },
                  "externalSource": {
                    "type": "string",
                    "nullable": true,
                    "example": "woocommerce"
                  },
                  "externalOrderId": {
                    "type": "string",
                    "nullable": true,
                    "example": "10234"
                  },
                  "externalOrderNumber": {
                    "type": "string",
                    "nullable": true,
                    "example": "#10234"
                  }
                }
              }
            }
          }
        ]
      },
      "KsefSendResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "description": "Dwie postacie: przyjęta od razu (ksefNumber obecne) albo w trakcie (status = \"processing\").",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "ksefNumber": {
                    "type": "string",
                    "nullable": true,
                    "example": "5271012345-20260926-AABBCCDDEEFF-01",
                    "description": "Numer KSeF, gdy faktura została przyjęta w oknie oczekiwania. Brak = status processing."
                  },
                  "referenceNumber": {
                    "type": "string",
                    "nullable": true,
                    "example": "20260926-SE-AABBCCDDEE-112233445566-01"
                  },
                  "invoiceNumber": {
                    "type": "string",
                    "nullable": true,
                    "example": "FV/1/09/2026"
                  },
                  "ordinalNumber": {
                    "type": "integer",
                    "nullable": true,
                    "example": 1
                  },
                  "status": {
                    "oneOf": [
                      {
                        "type": "string",
                        "enum": [
                          "processing"
                        ],
                        "description": "KSeF nadal przetwarza fakturę: odpytuj GET /documents/{id}/ksef-status albo czekaj na webhook document.sentToKSeF / document.ksefRejected."
                      },
                      {
                        "type": "object",
                        "nullable": true,
                        "description": "Ostatni status z KSeF.",
                        "properties": {
                          "code": {
                            "type": "integer",
                            "example": 200
                          },
                          "description": {
                            "type": "string",
                            "example": "Przyjęto"
                          },
                          "details": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "example": []
                          }
                        }
                      }
                    ],
                    "example": {
                      "code": 200,
                      "description": "Przyjęto",
                      "details": []
                    }
                  },
                  "sessionReferenceNumber": {
                    "type": "string",
                    "nullable": true
                  },
                  "invoiceReferenceNumber": {
                    "type": "string",
                    "nullable": true
                  },
                  "documentNumber": {
                    "type": "string",
                    "nullable": true,
                    "example": "FV/1/09/2026"
                  },
                  "hasUpo": {
                    "type": "boolean",
                    "example": true
                  },
                  "sendMode": {
                    "type": "string",
                    "example": "instant"
                  }
                }
              }
            }
          }
        ]
      },
      "KsefStatusResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "documentId": {
                    "type": "string",
                    "example": "681a3b2c4d5e6f7a8b9c0d1e"
                  },
                  "documentNumber": {
                    "type": "string",
                    "example": "FV/1/09/2026"
                  },
                  "state": {
                    "type": "string",
                    "enum": [
                      "not_sent",
                      "processing",
                      "sent",
                      "failed"
                    ],
                    "example": "sent",
                    "description": "sent i failed są stanami końcowymi."
                  },
                  "ksefNumber": {
                    "type": "string",
                    "nullable": true,
                    "example": "5271012345-20260926-AABBCCDDEEFF-01"
                  },
                  "ksefReferenceNumber": {
                    "type": "string",
                    "nullable": true
                  },
                  "ksefStatus": {
                    "type": "object",
                    "nullable": true,
                    "description": "Ostatni status z KSeF.",
                    "properties": {
                      "code": {
                        "type": "integer",
                        "example": 200
                      },
                      "description": {
                        "type": "string",
                        "example": "Przyjęto"
                      },
                      "details": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "example": []
                      }
                    }
                  },
                  "lastError": {
                    "type": "object",
                    "nullable": true,
                    "description": "Powód odrzucenia (state = failed).",
                    "properties": {
                      "code": {
                        "type": "integer",
                        "example": 405
                      },
                      "message": {
                        "type": "string",
                        "example": "Błąd walidacji semantycznej"
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "details": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "sentAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": "2026-09-26T10:30:00.000Z"
                  },
                  "processedAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": "2026-09-26T10:30:00.000Z"
                  },
                  "updatedAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": "2026-09-26T10:30:00.000Z"
                  }
                }
              }
            }
          }
        ]
      },
      "ClientExternal": {
        "type": "object",
        "description": "Kontrahent (nabywca lub dostawca) zapisany w kartotece.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "company",
              "person",
              null
            ],
            "example": "company"
          },
          "contractorType": {
            "type": "string",
            "nullable": true,
            "enum": [
              "client",
              "supplier",
              null
            ],
            "example": "client"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "example": "Acme Sp. z o.o."
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "nip": {
            "type": "string",
            "nullable": true,
            "example": "5261040828"
          },
          "vatUE": {
            "type": "string",
            "nullable": true
          },
          "identifierType": {
            "type": "string",
            "nullable": true,
            "example": "nip"
          },
          "otherTaxIdentifier": {
            "type": "string",
            "nullable": true
          },
          "idWew": {
            "type": "string",
            "nullable": true
          },
          "regon": {
            "type": "string",
            "nullable": true
          },
          "krs": {
            "type": "string",
            "nullable": true
          },
          "bdo": {
            "type": "string",
            "nullable": true
          },
          "pesel": {
            "type": "string",
            "nullable": true
          },
          "idNumber": {
            "type": "string",
            "nullable": true
          },
          "street": {
            "type": "string",
            "nullable": true,
            "example": "Marszałkowska 1"
          },
          "postalCode": {
            "type": "string",
            "nullable": true,
            "example": "00-001"
          },
          "city": {
            "type": "string",
            "nullable": true,
            "example": "Warszawa"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "example": "Polska"
          },
          "countryCode": {
            "type": "string",
            "nullable": true,
            "example": "PL"
          },
          "phoneNumber": {
            "type": "string",
            "nullable": true
          },
          "fax": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "emailAddresses": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "www": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "fieldsToShow": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          }
        }
      },
      "ClientInput": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "company",
              "person"
            ],
            "description": "Rodzaj kontrahenta: firma (wymagane name) albo osoba (wymagane firstName i lastName)."
          },
          "contractorType": {
            "type": "string",
            "enum": [
              "client",
              "supplier"
            ],
            "description": "Rola: nabywca (client, domyślnie) albo dostawca (supplier)."
          },
          "identifierType": {
            "type": "string",
            "enum": [
              "nip",
              "vatEu",
              "idWew",
              "other",
              "none"
            ],
            "description": "Który identyfikator wskazuje kontrahenta w KSeF. nip: polska firma, nip = 10 cyfr, np. 5261040828 (spacje, myślniki i prefiks PL są usuwane, sprawdzana jest cyfra kontrolna). vatEu: kontrahent z UE, numer VAT UE z prefiksem kraju w vatUE, np. kontrahent z Niemiec: identifierType=vatEu, vatUE=DE123456789 (Grecja ma prefiks EL; Irlandia Północna XI nie jest krajem UE w KSeF, podaj ją jako other). other: kontrahent spoza UE (albo z UE bez numeru VAT UE), kraj i identyfikator, np. identifierType=other, countryCode=US, otherTaxIdentifier=12-3456789. idWew: jednostka wewnętrzna (np. przedszkole gminy) używana jako odbiorca dokumentu, idWew=NIP-NNNNN. none: osoba prywatna albo brak identyfikatora. Bez identifierType serwer ustala typ z danych: polski NIP w nip to nip, numer VAT UE kraju UE (także wpisany w nip) to vatEu i trafia do vatUE, identyfikator kraju spoza UE to other, brak identyfikatora to none; ustalony typ i każde przeniesienie numeru zwraca w data.warnings. Podawaj identifierType jawnie. Sprzeczne dane (np. nip z numerem DE..., vatEu z numerem PL... albo XI..., błędna cyfra kontrolna NIP-u): 422 VALIDATION_ERROR z nazwą pola.",
            "example": "nip"
          },
          "name": {
            "type": "string",
            "description": "Nazwa firmy (wymagana dla type=company).",
            "example": "Acme Sp. z o.o."
          },
          "firstName": {
            "type": "string",
            "description": "Imię (wymagane dla type=person)."
          },
          "lastName": {
            "type": "string",
            "description": "Nazwisko (wymagane dla type=person)."
          },
          "nip": {
            "type": "string",
            "description": "Polski NIP (identifierType=nip): 10 cyfr; spacje, myślniki i prefiks PL są usuwane, sprawdzana jest cyfra kontrolna. Nie wpisuj tu zagranicznego numeru VAT: numer VAT UE podaj w vatUE.",
            "example": "5261040828"
          },
          "vatUE": {
            "type": "string",
            "description": "Numer VAT UE z prefiksem kraju, np. DE123456789, ATU12345678, EL123456789 (Grecja). Zapisywany wielkimi literami, bez spacji; numer bez prefiksu dostaje prefiks z countryCode. Polska firma z identifierType=nip może mieć tu numer PL i ten sam NIP (WDT).",
            "example": "DE123456789"
          },
          "idWew": {
            "type": "string",
            "description": "Identyfikator wewnętrzny jednostki przy identifierType=idWew: NIP-NNNNN (10 cyfr NIP, myślnik, 5 cyfr), np. 5252248481-16006."
          },
          "otherTaxIdentifier": {
            "type": "string",
            "description": "Identyfikator podatkowy przy identifierType=other (KSeF NrID), np. 12-3456789 dla firmy z USA; najwyżej 50 znaków, wymaga countryCode."
          },
          "regon": {
            "type": "string"
          },
          "krs": {
            "type": "string"
          },
          "bdo": {
            "type": "string"
          },
          "pesel": {
            "type": "string"
          },
          "idNumber": {
            "type": "string",
            "description": "Numer dokumentu tożsamości (osoba)."
          },
          "street": {
            "type": "string",
            "description": "Ulica z numerem.",
            "example": "Marszałkowska 1"
          },
          "postalCode": {
            "type": "string",
            "example": "00-001"
          },
          "city": {
            "type": "string",
            "example": "Warszawa"
          },
          "country": {
            "type": "string",
            "description": "Nazwa kraju, np. Polska.",
            "example": "Polska"
          },
          "countryCode": {
            "type": "string",
            "description": "Kod kraju ISO 3166-1 alpha-2, np. PL, DE, GR. Przy vatEu bez countryCode przyjmowany z prefiksu numeru VAT UE.",
            "example": "PL"
          },
          "phoneNumber": {
            "type": "string"
          },
          "fax": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "description": "Główny adres e-mail kontrahenta (nieprawidłowy adres: 422 z polem email)."
          },
          "www": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "description": "Notatka wewnętrzna o kontrahencie."
          },
          "emailAddresses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Dodatkowe adresy e-mail do wysyłki dokumentów (nieprawidłowy adres: 422 z polem emailAddresses)."
          },
          "fieldsToShow": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Pola dodatkowe pokazywane na dokumencie (np. regon, krs)."
          }
        },
        "description": "Dane kontrahenta (tworzenie i pełna aktualizacja)."
      },
      "PartyIdentifierWarning": {
        "type": "object",
        "description": "Informacja, jak odczytano identyfikatory kontrahenta: ustalony identifierType, przeniesiony numer, ustalony kraj, prefiks EL zamiast GR, pominięte pole.",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "IDENTIFIER_TYPE_INFERRED",
              "IDENTIFIER_MOVED",
              "IDENTIFIER_IGNORED",
              "COUNTRY_CODE_INFERRED",
              "VAT_UE_PREFIX_NORMALIZED"
            ],
            "example": "IDENTIFIER_MOVED"
          },
          "field": {
            "type": "string",
            "example": "buyer.vatUE",
            "description": "Pole, którego dotyczy (z prefiksem buyer. albo receiver. przy dokumentach)."
          },
          "message": {
            "type": "string",
            "example": "Numer DE123456789 przeniesiono z pola nip do vatUE: pole nip jest tylko na polski NIP."
          }
        },
        "required": [
          "code",
          "field",
          "message"
        ]
      },
      "ClientResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "client": {
                    "$ref": "#/components/schemas/ClientExternal"
                  },
                  "warnings": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/PartyIdentifierWarning"
                    },
                    "description": "Jak odczytano identyfikatory kontrahenta (pusta lista, gdy podano je jawnie i poprawnie)."
                  }
                }
              }
            }
          }
        ]
      },
      "ClientListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "clients": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ClientExternal"
                    }
                  },
                  "currentPage": {
                    "type": "integer",
                    "example": 1,
                    "description": "Numer bieżącej strony (od 1)."
                  },
                  "totalPages": {
                    "type": "integer",
                    "example": 5,
                    "description": "Liczba stron."
                  },
                  "totalCount": {
                    "type": "integer",
                    "example": 50,
                    "description": "Liczba wszystkich pasujących rekordów."
                  },
                  "itemsPerPage": {
                    "type": "integer",
                    "example": 10,
                    "description": "Rozmiar strony (maks. 100)."
                  },
                  "searchQuery": {
                    "type": "string",
                    "example": "",
                    "description": "Użyty filtr tekstowy (pusty, gdy brak)."
                  }
                }
              }
            }
          }
        ]
      },
      "ProductExternal": {
        "type": "object",
        "description": "Produkt lub usługa z kartoteki.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "example": "Usługa programistyczna"
          },
          "gtu": {
            "type": "string",
            "nullable": true
          },
          "pkwiu": {
            "type": "string",
            "nullable": true
          },
          "unitOfMeasure": {
            "type": "string",
            "nullable": true,
            "example": "szt."
          },
          "discount": {
            "type": "number",
            "nullable": true,
            "example": 0
          },
          "quantity": {
            "type": "number",
            "nullable": true,
            "example": 1
          },
          "netPrice": {
            "type": "number",
            "nullable": true,
            "example": 100
          },
          "netValue": {
            "type": "number",
            "nullable": true,
            "example": 100
          },
          "grossValue": {
            "type": "number",
            "nullable": true,
            "example": 123
          },
          "amountOfVat": {
            "type": "number",
            "nullable": true,
            "example": 23
          },
          "vatRate": {
            "oneOf": [
              {
                "type": "number"
              },
              {
                "type": "string"
              }
            ],
            "nullable": true,
            "example": 23
          },
          "taxSymbol": {
            "type": "string",
            "nullable": true,
            "example": "%"
          },
          "currency": {
            "type": "string",
            "nullable": true,
            "example": "PLN"
          },
          "productType": {
            "type": "string",
            "enum": [
              "goods",
              "service"
            ],
            "nullable": true,
            "example": "goods",
            "description": "goods = towar (prowadzi stany magazynowe), service = usługa; null = usługa (produkty sprzed modułu Magazyn)."
          },
          "sku": {
            "type": "string",
            "nullable": true
          },
          "ean": {
            "type": "string",
            "nullable": true
          },
          "purchasePrice": {
            "type": "number",
            "nullable": true,
            "description": "Cena zakupu netto."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          }
        }
      },
      "ProductInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Nazwa produktu lub usługi.",
            "example": "Usługa programistyczna"
          },
          "gtu": {
            "type": "string",
            "nullable": true,
            "enum": [
              "GTU_01",
              "GTU_02",
              "GTU_03",
              "GTU_04",
              "GTU_05",
              "GTU_06",
              "GTU_07",
              "GTU_08",
              "GTU_09",
              "GTU_10",
              "GTU_11",
              "GTU_12",
              "GTU_13",
              null
            ],
            "description": "Kod GTU (GTU_01 ... GTU_13) albo pusty."
          },
          "pkwiu": {
            "type": "string",
            "nullable": true
          },
          "unitOfMeasure": {
            "type": "string",
            "description": "Jednostka miary, np. szt., godz., usł.",
            "example": "szt."
          },
          "currency": {
            "type": "string",
            "example": "PLN"
          },
          "quantity": {
            "type": "number",
            "example": 1
          },
          "netPrice": {
            "type": "number",
            "description": "Cena netto jednostkowa (przed rabatem). Wymagana jest jedna cena: netPrice ALBO grossPrice; obie naraz = 422.",
            "example": 100
          },
          "grossPrice": {
            "type": "number",
            "description": "Cena brutto jednostkowa (przed rabatem). Wymagana jest jedna cena: netPrice ALBO grossPrice; obie naraz = 422."
          },
          "netValue": {
            "type": "number",
            "description": "Wartość netto pozycji (liczona automatycznie, gdy pominięta)."
          },
          "grossValue": {
            "type": "number",
            "description": "Wartość brutto pozycji (liczona automatycznie, gdy pominięta)."
          },
          "amountOfVat": {
            "type": "number",
            "description": "Kwota VAT (liczona automatycznie, gdy pominięta)."
          },
          "vatRate": {
            "oneOf": [
              {
                "type": "number"
              },
              {
                "type": "string"
              }
            ],
            "description": "Stawka VAT: liczba (23, 8, 5; zagraniczna 19 poza KSeF) albo kod specjalny (zw, np I, oo, 0 WDT, 0 EX, 0 KR). Pominięta: domyślna stawka konta (ustawienia), jak na pozycjach dokumentu.",
            "example": 23
          },
          "discount": {
            "type": "number",
            "description": "Rabat w procentach (0-100), zapisywany w kartotece; wartość netto uwzględnia rabat.",
            "example": 0
          },
          "productType": {
            "type": "string",
            "enum": [
              "goods",
              "service"
            ],
            "description": "Moduł Magazyn: goods = towar (prowadzi stany), service = usługa. Brak = usługa."
          },
          "sku": {
            "type": "string",
            "description": "Kod magazynowy (SKU)."
          },
          "ean": {
            "type": "string",
            "description": "Kod kreskowy EAN."
          },
          "purchasePrice": {
            "type": "number",
            "minimum": 0,
            "description": "Cena zakupu netto: domyślna cena przyjęć PZ/PW."
          }
        },
        "description": "Dane produktu przy tworzeniu: wymagane name i jedna cena (netPrice albo grossPrice); kwoty są przeliczane z ceny, stawki VAT i rabatu."
      },
      "ProductUpdateInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "description": "Dane produktu przy aktualizacji: nowa cena bez wartości = przeliczenie; wartości podane wprost muszą się zgadzać (inaczej 422).",
        "properties": {
          "name": {
            "type": "string",
            "description": "Nazwa produktu lub usługi.",
            "example": "Usługa programistyczna"
          },
          "gtu": {
            "type": "string",
            "nullable": true,
            "enum": [
              "GTU_01",
              "GTU_02",
              "GTU_03",
              "GTU_04",
              "GTU_05",
              "GTU_06",
              "GTU_07",
              "GTU_08",
              "GTU_09",
              "GTU_10",
              "GTU_11",
              "GTU_12",
              "GTU_13",
              null
            ],
            "description": "Kod GTU (GTU_01 ... GTU_13) albo pusty."
          },
          "pkwiu": {
            "type": "string",
            "nullable": true
          },
          "unitOfMeasure": {
            "type": "string",
            "description": "Jednostka miary, np. szt., godz., usł.",
            "example": "szt."
          },
          "taxSymbol": {
            "type": "string",
            "description": "Symbol stawki VAT, np. % albo zw."
          },
          "currency": {
            "type": "string",
            "example": "PLN"
          },
          "quantity": {
            "type": "number",
            "example": 1
          },
          "netPrice": {
            "type": "number",
            "description": "Cena netto jednostkowa (przed rabatem). Bez netValue/amountOfVat/grossValue wartości są przeliczane."
          },
          "netValue": {
            "type": "number",
            "description": "Wartość netto; podana wprost musi się zgadzać z ceną, stawką i sumą (inaczej 422)."
          },
          "grossValue": {
            "type": "number",
            "description": "Wartość brutto; musi się równać netValue + amountOfVat."
          },
          "amountOfVat": {
            "type": "number",
            "description": "Kwota VAT; musi odpowiadać stawce od wartości netto."
          },
          "vatRate": {
            "oneOf": [
              {
                "type": "number"
              },
              {
                "type": "string"
              }
            ],
            "description": "Stawka VAT: liczba (23, 8, 5; zagraniczna 19 poza KSeF) albo kod specjalny (zw, np I, oo, 0 WDT, 0 EX, 0 KR)."
          },
          "discount": {
            "type": "number",
            "description": "Rabat w procentach (0-100). Zapisywany tylko, gdy pole jest w żądaniu; zmiana przelicza wartości."
          },
          "productType": {
            "type": "string",
            "enum": [
              "goods",
              "service"
            ],
            "description": "Moduł Magazyn: goods albo service. Zapisywane tylko, gdy pole jest w żądaniu."
          },
          "sku": {
            "type": "string",
            "description": "Kod magazynowy (SKU)."
          },
          "ean": {
            "type": "string",
            "description": "Kod kreskowy EAN."
          },
          "purchasePrice": {
            "type": "number",
            "minimum": 0,
            "description": "Cena zakupu netto: domyślna cena przyjęć PZ/PW."
          }
        }
      },
      "ProductResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "product": {
                    "$ref": "#/components/schemas/ProductExternal"
                  }
                }
              }
            }
          }
        ]
      },
      "ProductListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "products": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ProductExternal"
                    }
                  },
                  "currentPage": {
                    "type": "integer",
                    "example": 1,
                    "description": "Numer bieżącej strony (od 1)."
                  },
                  "totalPages": {
                    "type": "integer",
                    "example": 5,
                    "description": "Liczba stron."
                  },
                  "totalCount": {
                    "type": "integer",
                    "example": 50,
                    "description": "Liczba wszystkich pasujących rekordów."
                  },
                  "itemsPerPage": {
                    "type": "integer",
                    "example": 10,
                    "description": "Rozmiar strony (maks. 100)."
                  },
                  "searchQuery": {
                    "type": "string",
                    "example": "",
                    "description": "Użyty filtr tekstowy (pusty, gdy brak)."
                  }
                }
              }
            }
          }
        ]
      },
      "WarehouseExternal": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "example": "Magazyn główny"
          },
          "symbol": {
            "type": "string",
            "nullable": true,
            "example": "MAG1",
            "description": "Symbol używany w numeracji dokumentów magazynowych."
          },
          "address": {
            "type": "string",
            "nullable": true,
            "example": "ul. Prosta 1, 00-001 Warszawa"
          },
          "isDefault": {
            "type": "boolean",
            "example": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          }
        }
      },
      "WarehouseInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "example": "Magazyn główny"
          },
          "symbol": {
            "type": "string",
            "example": "MAG1",
            "description": "Symbol używany w numeracji dokumentów magazynowych."
          },
          "address": {
            "type": "string",
            "example": "ul. Prosta 1, 00-001 Warszawa"
          },
          "isDefault": {
            "type": "boolean",
            "example": false
          }
        }
      },
      "WarehouseResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "warehouse": {
                    "$ref": "#/components/schemas/WarehouseExternal"
                  }
                }
              }
            }
          }
        ]
      },
      "StockMovementExternal": {
        "type": "object",
        "description": "Wiersz księgi magazynowej. Stan produktu = suma ruchów.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "productId": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d2a"
          },
          "warehouseId": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d3b"
          },
          "quantity": {
            "type": "number",
            "example": -2,
            "description": "Dodatnia = przyjęcie, ujemna = wydanie."
          },
          "unitCost": {
            "type": "number",
            "nullable": true,
            "example": 12.5,
            "description": "Koszt jednostkowy netto (przy przyjęciach)."
          },
          "type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "PZ",
              "WZ",
              "PW",
              "RW",
              "MM_OUT",
              "MM_IN",
              "INW",
              "WYCENA",
              null
            ],
            "example": "WZ"
          },
          "documentId": {
            "type": "string",
            "nullable": true,
            "description": "Dokument magazynowy, z którego pochodzi ruch (null dla korekt ręcznych)."
          },
          "documentNumber": {
            "type": "string",
            "nullable": true,
            "example": "WZ/3/09/2026"
          },
          "date": {
            "type": "string",
            "nullable": true,
            "example": "2026-09-26",
            "description": "Data ruchu (YYYY-MM-DD)."
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "employeeId": {
            "type": "string",
            "nullable": true,
            "description": "Pracownik, który zapisał ruch; null dla właściciela."
          },
          "employeeName": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          }
        }
      },
      "StockMovementsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "movements": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/StockMovementExternal"
                    }
                  },
                  "currentPage": {
                    "type": "integer",
                    "example": 1,
                    "description": "Numer bieżącej strony (od 1)."
                  },
                  "totalPages": {
                    "type": "integer",
                    "example": 5,
                    "description": "Liczba stron."
                  },
                  "totalCount": {
                    "type": "integer",
                    "example": 50,
                    "description": "Liczba wszystkich pasujących rekordów."
                  },
                  "itemsPerPage": {
                    "type": "integer",
                    "example": 10,
                    "description": "Rozmiar strony (maks. 100)."
                  },
                  "searchQuery": {
                    "type": "string",
                    "example": "",
                    "description": "Użyty filtr tekstowy (pusty, gdy brak)."
                  }
                }
              }
            }
          }
        ]
      },
      "WarehouseListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "warehouses": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/WarehouseExternal"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "StockAdjustmentInput": {
        "type": "object",
        "required": [
          "productId",
          "warehouseId",
          "quantity"
        ],
        "properties": {
          "productId": {
            "type": "string",
            "example": "681a3b2c4d5e6f7a8b9c0d1e",
            "description": "ID produktu z kartoteki."
          },
          "warehouseId": {
            "type": "string",
            "example": "681a3b2c4d5e6f7a8b9c0d1f"
          },
          "quantity": {
            "type": "number",
            "example": 25,
            "description": "Zmiana stanu: dodatnia = przyjęcie, ujemna = wydanie."
          },
          "unitCost": {
            "type": "number",
            "nullable": true,
            "example": 12.5,
            "description": "Koszt jednostkowy netto (podstawa wyceny dla przyjęć)."
          },
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-09-26",
            "description": "YYYY-MM-DD, domyślnie dzisiaj."
          },
          "note": {
            "type": "string",
            "example": "Bilans otwarcia"
          }
        }
      },
      "StockAdjustmentResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "Stock adjustment recorded."
              },
              "data": {
                "type": "object",
                "properties": {
                  "movement": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "example": "681a3b2c4d5e6f7a8b9c0d1e"
                      },
                      "productId": {
                        "type": "string"
                      },
                      "warehouseId": {
                        "type": "string"
                      },
                      "quantity": {
                        "type": "number",
                        "example": 25
                      },
                      "unitCost": {
                        "type": "number",
                        "nullable": true,
                        "example": 12.5
                      },
                      "type": {
                        "type": "string",
                        "example": "INW"
                      },
                      "date": {
                        "type": "string",
                        "example": "2026-09-26"
                      },
                      "note": {
                        "type": "string",
                        "nullable": true
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "StockReportResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "levels": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "productId": {
                          "type": "string",
                          "example": "681a3b2c4d5e6f7a8b9c0d1e"
                        },
                        "warehouseId": {
                          "type": "string",
                          "example": "681a3b2c4d5e6f7a8b9c0d1f"
                        },
                        "quantity": {
                          "type": "number",
                          "example": 12
                        }
                      }
                    }
                  },
                  "asOf": {
                    "type": "string",
                    "nullable": true,
                    "example": null,
                    "description": "Data raportu historycznego (YYYY-MM-DD) albo null dla stanu bieżącego."
                  }
                }
              }
            }
          }
        ]
      },
      "WzFromInvoiceInput": {
        "type": "object",
        "properties": {
          "warehouseId": {
            "type": "string",
            "example": "681a3b2c4d5e6f7a8b9c0d1f",
            "description": "Magazyn, z którego wydawany jest towar. Domyślnie magazyn domyślny."
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "description": "Data wystawienia WZ (RRRR-MM-DD). Domyślnie data wystawienia faktury."
          },
          "allowNegativeStock": {
            "type": "boolean",
            "description": "true = wystaw mimo braku towaru (stan zejdzie poniżej zera). Domyślnie brak towaru odrzuca WZ (422 STOCK_SHORTAGE)."
          }
        }
      },
      "WzFromInvoiceResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "document": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "example": "681a3b2c4d5e6f7a8b9c0d1e"
                      },
                      "documentType": {
                        "type": "string",
                        "example": "WZ"
                      },
                      "documentNumber": {
                        "type": "string",
                        "example": "WZ/3/09/2026"
                      },
                      "warehouseId": {
                        "type": "string"
                      },
                      "grossSum": {
                        "type": "number",
                        "example": 1230
                      },
                      "linkedInvoiceId": {
                        "type": "string"
                      }
                    }
                  },
                  "skipped": {
                    "type": "array",
                    "description": "Pozycje faktury pominięte na WZ (usługi, produkty bez kartoteki).",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "EmployeeExternal": {
        "type": "object",
        "description": "Konto pracownicze. Nigdy nie zawiera hasła.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "firstName": {
            "type": "string",
            "nullable": true,
            "example": "Jan"
          },
          "lastName": {
            "type": "string",
            "nullable": true,
            "example": "Kowalski"
          },
          "emailAddress": {
            "type": "string",
            "nullable": true,
            "example": "jan@firma.pl"
          },
          "permissions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "documents:read",
              "documents:write"
            ]
          },
          "isActive": {
            "type": "boolean",
            "example": true
          },
          "lastLoginAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          }
        }
      },
      "EmployeeInput": {
        "type": "object",
        "required": [
          "firstName",
          "lastName",
          "emailAddress",
          "password"
        ],
        "properties": {
          "firstName": {
            "type": "string",
            "example": "Jan"
          },
          "lastName": {
            "type": "string",
            "example": "Kowalski"
          },
          "emailAddress": {
            "type": "string",
            "format": "email",
            "example": "jan@firma.pl",
            "description": "Globalnie unikalny e-mail logowania."
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "description": "Minimum 8 znaków."
          },
          "permissions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "documents:read",
              "documents:write"
            ],
            "description": "Klucze z GET /employees/permissions. Nieznane klucze są ignorowane; uprawnienia implikowane (pole implies) dodawane automatycznie."
          }
        }
      },
      "EmployeeUpdateInput": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "emailAddress": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "description": "Nowe hasło; pomiń, aby zachować obecne."
          },
          "permissions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Pełne zastąpienie listy uprawnień; uprawnienia implikowane dodawane automatycznie."
          },
          "isActive": {
            "type": "boolean",
            "description": "false dezaktywuje konto natychmiast i kończy jego sesje."
          }
        }
      },
      "EmployeeResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "employee": {
                    "$ref": "#/components/schemas/EmployeeExternal"
                  }
                }
              }
            }
          }
        ]
      },
      "ActivityFeedItem": {
        "type": "object",
        "description": "Wpis dziennika aktywności: akcja na dokumencie, logowanie lub zmiana konta pracownika, operacja magazynowa.",
        "properties": {
          "id": {
            "type": "string",
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "scope": {
            "type": "string",
            "enum": [
              "auth",
              "management",
              "document",
              "warehouse"
            ],
            "example": "document",
            "description": "auth = logowania, management = zmiany konta pracownika, document = akcje na dokumentach, warehouse = magazyn."
          },
          "type": {
            "type": "string",
            "example": "CREATE",
            "description": "Rodzaj zdarzenia, np. CREATE, UPDATE, SENT_BY_EMAIL, KSEF_SENT, PAYMENT_RECEIVED, LOGIN, PERMISSIONS_CHANGED, ADJUSTMENT."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "employeeId": {
            "type": "string",
            "nullable": true,
            "description": "Pracownik, który wykonał akcję; null dla właściciela."
          },
          "employeeName": {
            "type": "string",
            "nullable": true
          },
          "entityId": {
            "type": "string",
            "nullable": true,
            "description": "Identyfikator dotkniętego zasobu (np. dokumentu)."
          },
          "entityName": {
            "type": "string",
            "nullable": true,
            "example": "FV/12/09/2026",
            "description": "Numer dokumentu albo nazwa zasobu."
          },
          "entityType": {
            "type": "string",
            "nullable": true,
            "example": "DOCUMENT"
          },
          "entityDeleted": {
            "type": "boolean",
            "example": false,
            "description": "true, gdy dokument został później usunięty."
          },
          "changes": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Różnice pól przy edycji."
          },
          "data": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Szczegóły zdarzenia (np. origin, adresaci e-maila, wynik KSeF)."
          }
        }
      },
      "ActivityFeedResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ActivityFeedItem"
                    }
                  },
                  "hasMore": {
                    "type": "boolean",
                    "example": true,
                    "description": "Czy są starsze wpisy."
                  },
                  "nextBefore": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": "2026-09-26T10:30:00.000Z",
                    "description": "Kursor: podaj jako `before`, żeby pobrać kolejną stronę."
                  }
                }
              }
            }
          }
        ]
      },
      "EmployeeActivityResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "employee": {
                    "$ref": "#/components/schemas/EmployeeExternal"
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ActivityFeedItem"
                    }
                  },
                  "hasMore": {
                    "type": "boolean",
                    "example": false
                  },
                  "nextBefore": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": null
                  }
                }
              }
            }
          }
        ]
      },
      "EmployeeCreatedResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "Employee account created."
              },
              "data": {
                "type": "object",
                "properties": {
                  "employee": {
                    "$ref": "#/components/schemas/EmployeeExternal"
                  },
                  "availablePermissions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Wszystkie klucze uprawnień, do wyboru w kolejnych aktualizacjach."
                  }
                }
              }
            }
          }
        ]
      },
      "EmployeeListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "employees": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/EmployeeExternal"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "EmployeePermissionsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "permissions": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string",
                          "example": "documents:read"
                        },
                        "group": {
                          "type": "string",
                          "example": "documents"
                        },
                        "label": {
                          "type": "string",
                          "example": "Podgląd dokumentów"
                        },
                        "description": {
                          "type": "string"
                        },
                        "implies": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Uprawnienia przyznawane automatycznie razem z tym kluczem."
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "RecurringRuleExternal": {
        "type": "object",
        "description": "Reguła dokumentu cyklicznego. Pełny szablon dokumentu nie jest zwracany; documentSummary opisuje, co reguła generuje.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "example": "Abonament miesięczny"
          },
          "status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "ACTIVE",
              "PAUSED",
              "FINISHED",
              null
            ],
            "example": "ACTIVE"
          },
          "mode": {
            "type": "string",
            "nullable": true,
            "enum": [
              "AUTO",
              "DRAFT",
              "REMINDER",
              null
            ],
            "example": "AUTO",
            "description": "AUTO wystawia dokument, DRAFT tworzy szkic, REMINDER tylko przypomina."
          },
          "documentSummary": {
            "type": "object",
            "properties": {
              "documentType": {
                "type": "string",
                "nullable": true,
                "example": "FakturaVAT"
              },
              "buyerName": {
                "type": "string",
                "nullable": true,
                "example": "Acme Sp. z o.o."
              },
              "grossSum": {
                "type": "number",
                "nullable": true,
                "example": 1230
              },
              "currency": {
                "type": "string",
                "example": "PLN"
              }
            }
          },
          "schedule": {
            "type": "object",
            "nullable": true,
            "description": "Harmonogram generacji (częstotliwość, dzień, zakres dat); kształt zgodny z ustawieniami w aplikacji.",
            "additionalProperties": true
          },
          "automation": {
            "type": "object",
            "properties": {
              "sendEmail": {
                "type": "boolean",
                "example": true
              },
              "emailRecipients": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "sendToKsef": {
                "type": "boolean",
                "example": false
              },
              "notify": {
                "type": "object",
                "properties": {
                  "onGenerate": {
                    "type": "boolean"
                  },
                  "dayBefore": {
                    "type": "boolean"
                  },
                  "channels": {
                    "type": "object",
                    "properties": {
                      "email": {
                        "type": "boolean"
                      },
                      "pushWeb": {
                        "type": "boolean"
                      },
                      "pushMobile": {
                        "type": "boolean"
                      }
                    }
                  }
                }
              },
              "notifyOnGenerate": {
                "type": "boolean",
                "deprecated": true,
                "description": "Zastąpione przez notify.onGenerate razem z notify.channels.email."
              },
              "notifyDayBefore": {
                "type": "boolean",
                "deprecated": true,
                "description": "Zastąpione przez notify.dayBefore razem z notify.channels.email."
              }
            }
          },
          "payment": {
            "type": "object",
            "nullable": true,
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "PAID",
                  "UNPAID"
                ]
              },
              "deadlineDays": {
                "type": "integer",
                "example": 14
              }
            }
          },
          "numberingSymbol": {
            "type": "string",
            "nullable": true,
            "example": "FV/"
          },
          "refreshSellerData": {
            "type": "boolean",
            "example": true
          },
          "sourceDocumentId": {
            "type": "string",
            "nullable": true
          },
          "nextRunAt": {
            "type": "string",
            "nullable": true,
            "example": "2026-10-01",
            "description": "Data najbliższej generacji (YYYY-MM-DD) albo null."
          },
          "lastRunAt": {
            "type": "string",
            "nullable": true,
            "example": "2026-09-01"
          },
          "occurrencesCount": {
            "type": "integer",
            "example": 3
          },
          "documentsIssuedCount": {
            "type": "integer",
            "example": 3
          },
          "skipDates": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": []
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          }
        }
      },
      "RecurringRunExternal": {
        "type": "object",
        "description": "Wpis historii generacji reguły.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "plannedDate": {
            "type": "string",
            "nullable": true,
            "example": "2026-09-01"
          },
          "issueDate": {
            "type": "string",
            "nullable": true,
            "example": "2026-09-01"
          },
          "documentId": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1f"
          },
          "documentNumber": {
            "type": "string",
            "nullable": true,
            "example": "FV/7/09/2026"
          },
          "status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "GENERATED",
              "DRAFT",
              "REMINDED",
              "SKIPPED",
              "FAILED",
              "PENDING",
              null
            ],
            "example": "GENERATED"
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "emailSent": {
            "type": "boolean",
            "example": true
          },
          "ksefQueued": {
            "type": "boolean",
            "example": false
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          }
        }
      },
      "RecurringRuleResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "rule": {
                    "$ref": "#/components/schemas/RecurringRuleExternal"
                  }
                }
              }
            }
          }
        ]
      },
      "RecurringRuleListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "rules": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/RecurringRuleExternal"
                    }
                  },
                  "currentPage": {
                    "type": "integer",
                    "example": 1,
                    "description": "Numer bieżącej strony (od 1)."
                  },
                  "totalPages": {
                    "type": "integer",
                    "example": 5,
                    "description": "Liczba stron."
                  },
                  "totalCount": {
                    "type": "integer",
                    "example": 50,
                    "description": "Liczba wszystkich pasujących rekordów."
                  },
                  "itemsPerPage": {
                    "type": "integer",
                    "example": 10,
                    "description": "Rozmiar strony (maks. 100)."
                  },
                  "searchQuery": {
                    "type": "string",
                    "example": "",
                    "description": "Użyty filtr tekstowy (pusty, gdy brak)."
                  },
                  "summary": {
                    "type": "object",
                    "description": "Podsumowanie liczone po wszystkich regułach konta (niezależnie od filtra status).",
                    "properties": {
                      "total": {
                        "type": "integer",
                        "example": 3
                      },
                      "active": {
                        "type": "integer",
                        "example": 2
                      },
                      "paused": {
                        "type": "integer",
                        "example": 1
                      },
                      "finished": {
                        "type": "integer",
                        "example": 0
                      },
                      "nextRunAt": {
                        "type": "string",
                        "nullable": true,
                        "example": "2026-10-01"
                      },
                      "monthlyRecurringGross": {
                        "type": "number",
                        "example": 2460,
                        "description": "Miesięczny przychód brutto z aktywnych reguł, w PLN."
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "RecurringRuleHistoryResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "runs": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/RecurringRunExternal"
                    }
                  },
                  "currentPage": {
                    "type": "integer",
                    "example": 1,
                    "description": "Numer bieżącej strony (od 1)."
                  },
                  "totalPages": {
                    "type": "integer",
                    "example": 5,
                    "description": "Liczba stron."
                  },
                  "totalCount": {
                    "type": "integer",
                    "example": 50,
                    "description": "Liczba wszystkich pasujących rekordów."
                  },
                  "itemsPerPage": {
                    "type": "integer",
                    "example": 10,
                    "description": "Rozmiar strony (maks. 100)."
                  },
                  "searchQuery": {
                    "type": "string",
                    "example": "",
                    "description": "Użyty filtr tekstowy (pusty, gdy brak)."
                  }
                }
              }
            }
          }
        ]
      },
      "RecurringRuleToggleInput": {
        "type": "object",
        "required": [
          "active"
        ],
        "properties": {
          "active": {
            "type": "boolean",
            "description": "true = wznów (ACTIVE), false = wstrzymaj (PAUSED).",
            "example": false
          }
        }
      },
      "EmailAccountExternal": {
        "type": "object",
        "description": "Podłączona skrzynka nadawcza. Sekrety (hasło SMTP, tokeny OAuth) nigdy nie są zwracane.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "provider": {
            "type": "string",
            "nullable": true,
            "enum": [
              "smtp",
              "gmail",
              "outlook",
              null
            ],
            "example": "smtp"
          },
          "isOAuth": {
            "type": "boolean",
            "example": false,
            "description": "true dla Gmail i Outlook (OAuth), false dla SMTP."
          },
          "email": {
            "type": "string",
            "nullable": true,
            "example": "faktury@firma.pl"
          },
          "host": {
            "type": "string",
            "nullable": true,
            "example": "smtp.firma.pl",
            "description": "Tylko SMTP."
          },
          "port": {
            "type": "integer",
            "nullable": true,
            "example": 465
          },
          "secure": {
            "type": "boolean",
            "example": true,
            "description": "true = SSL (465), false = STARTTLS."
          },
          "verificationStatus": {
            "type": "string",
            "enum": [
              "unverified",
              "verified",
              "error"
            ],
            "example": "verified"
          },
          "isVerified": {
            "type": "integer",
            "enum": [
              0,
              1,
              2
            ],
            "example": 1,
            "description": "Kod jak w aplikacji: 0 = niezweryfikowane, 1 = zweryfikowane, 2 = ostatnia wysyłka zakończyła się błędem."
          },
          "isDefault": {
            "type": "boolean",
            "example": true
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "lastVerifiedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          }
        }
      },
      "EmailAccountResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "emailAccount": {
                    "$ref": "#/components/schemas/EmailAccountExternal"
                  }
                }
              }
            }
          }
        ]
      },
      "EmailAccountListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "emailAccounts": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/EmailAccountExternal"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "SettingsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "general": {
                    "type": "object",
                    "properties": {
                      "dateFormat": {
                        "type": "string",
                        "enum": [
                          "dd.MM.yyyy",
                          "dd/MM/yyyy",
                          "dd-MM-yyyy",
                          "yyyy-MM-dd",
                          "yyyy.MM.dd",
                          "MM/dd/yyyy",
                          "d MMMM yyyy",
                          "d MMM yyyy",
                          "dd.MM.yy"
                        ],
                        "example": "dd.MM.yyyy"
                      },
                      "newsletter": {
                        "type": "boolean",
                        "example": true
                      },
                      "dateFormatOptions": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "example": [
                          "dd.MM.yyyy",
                          "dd/MM/yyyy",
                          "dd-MM-yyyy",
                          "yyyy-MM-dd",
                          "yyyy.MM.dd",
                          "MM/dd/yyyy",
                          "d MMMM yyyy",
                          "d MMM yyyy",
                          "dd.MM.yy"
                        ]
                      }
                    }
                  },
                  "numbering": {
                    "type": "object",
                    "properties": {
                      "numberingType": {
                        "type": "string",
                        "enum": [
                          "MONTH",
                          "YEAR"
                        ],
                        "example": "MONTH"
                      },
                      "numberingFormat": {
                        "type": "string",
                        "enum": [
                          "/MM/YYYY",
                          "YYYY/MM/",
                          "/YYYY/MM",
                          "MM/YYYY/",
                          "/YYYY",
                          "YYYY/",
                          "-MM-YYYY",
                          "YYYY-MM-",
                          "-YYYY-MM",
                          "MM-YYYY-",
                          "-YYYY",
                          "YYYY-"
                        ],
                        "example": "/MM/YYYY"
                      },
                      "numberingTypeOptions": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "example": [
                          "MONTH",
                          "YEAR"
                        ]
                      },
                      "numberingFormatOptions": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "example": [
                          "/MM/YYYY",
                          "YYYY/MM/",
                          "/YYYY/MM",
                          "MM/YYYY/",
                          "/YYYY",
                          "YYYY/",
                          "-MM-YYYY",
                          "YYYY-MM-",
                          "-YYYY-MM",
                          "MM-YYYY-",
                          "-YYYY",
                          "YYYY-"
                        ]
                      },
                      "documentSymbols": {
                        "type": "object",
                        "description": "Prefiksy numerów per typ dokumentu; brakujący klucz = pusty prefiks.",
                        "properties": {
                          "Faktura": {
                            "type": "string",
                            "example": "F"
                          },
                          "FakturaVAT": {
                            "type": "string",
                            "example": "FV/"
                          },
                          "FakturaZaliczka": {
                            "type": "string",
                            "example": "FZ/"
                          },
                          "FakturaKorygujaca": {
                            "type": "string",
                            "example": "KOR/"
                          },
                          "FakturaKorygujacaZaliczkowa": {
                            "type": "string"
                          },
                          "FakturaKorygujacaRozliczeniowa": {
                            "type": "string"
                          },
                          "FakturaRozliczeniowa": {
                            "type": "string",
                            "example": "FK/"
                          },
                          "FakturaProforma": {
                            "type": "string",
                            "example": "FP/"
                          },
                          "FakturaProformaBezVAT": {
                            "type": "string"
                          },
                          "Zamowienie": {
                            "type": "string",
                            "example": "ZAM/"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "GeneralSettingsInput": {
        "type": "object",
        "required": [
          "dateFormat",
          "newsletter"
        ],
        "properties": {
          "dateFormat": {
            "type": "string",
            "enum": [
              "dd.MM.yyyy",
              "dd/MM/yyyy",
              "dd-MM-yyyy",
              "yyyy-MM-dd",
              "yyyy.MM.dd",
              "MM/dd/yyyy",
              "d MMMM yyyy",
              "d MMM yyyy",
              "dd.MM.yy"
            ],
            "description": "Format dat na dokumentach.",
            "example": "dd.MM.yyyy"
          },
          "newsletter": {
            "type": "boolean",
            "description": "Zgoda na newsletter.",
            "example": false
          }
        }
      },
      "GeneralSettingsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "General settings updated."
              },
              "data": {
                "type": "object",
                "properties": {
                  "dateFormat": {
                    "type": "string",
                    "enum": [
                      "dd.MM.yyyy",
                      "dd/MM/yyyy",
                      "dd-MM-yyyy",
                      "yyyy-MM-dd",
                      "yyyy.MM.dd",
                      "MM/dd/yyyy",
                      "d MMMM yyyy",
                      "d MMM yyyy",
                      "dd.MM.yy"
                    ],
                    "example": "dd.MM.yyyy"
                  },
                  "newsletter": {
                    "type": "boolean",
                    "example": false
                  }
                }
              }
            }
          }
        ]
      },
      "NumberingSettingsInput": {
        "type": "object",
        "required": [
          "numberingType",
          "numberingFormat",
          "documentSymbols"
        ],
        "properties": {
          "numberingType": {
            "type": "string",
            "enum": [
              "MONTH",
              "YEAR"
            ],
            "description": "Numeracja miesięczna (format musi zawierać MM) albo roczna.",
            "example": "MONTH"
          },
          "numberingFormat": {
            "type": "string",
            "enum": [
              "/MM/YYYY",
              "YYYY/MM/",
              "/YYYY/MM",
              "MM/YYYY/",
              "/YYYY",
              "YYYY/",
              "-MM-YYYY",
              "YYYY-MM-",
              "-YYYY-MM",
              "MM-YYYY-",
              "-YYYY",
              "YYYY-"
            ],
            "description": "Wzorzec części daty w numerze dokumentu.",
            "example": "/MM/YYYY"
          },
          "documentSymbols": {
            "type": "object",
            "description": "Prefiksy numerów per typ dokumentu; brakujący klucz = pusty prefiks.",
            "properties": {
              "Faktura": {
                "type": "string",
                "example": "F"
              },
              "FakturaVAT": {
                "type": "string",
                "example": "FV/"
              },
              "FakturaZaliczka": {
                "type": "string",
                "example": "FZ/"
              },
              "FakturaKorygujaca": {
                "type": "string",
                "example": "KOR/"
              },
              "FakturaKorygujacaZaliczkowa": {
                "type": "string"
              },
              "FakturaKorygujacaRozliczeniowa": {
                "type": "string"
              },
              "FakturaRozliczeniowa": {
                "type": "string",
                "example": "FK/"
              },
              "FakturaProforma": {
                "type": "string",
                "example": "FP/"
              },
              "FakturaProformaBezVAT": {
                "type": "string"
              },
              "Zamowienie": {
                "type": "string",
                "example": "ZAM/"
              }
            }
          }
        }
      },
      "NumberingSettingsResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "Numbering settings updated."
              },
              "data": {
                "type": "object",
                "properties": {
                  "numberingType": {
                    "type": "string",
                    "enum": [
                      "MONTH",
                      "YEAR"
                    ],
                    "example": "MONTH"
                  },
                  "numberingFormat": {
                    "type": "string",
                    "enum": [
                      "/MM/YYYY",
                      "YYYY/MM/",
                      "/YYYY/MM",
                      "MM/YYYY/",
                      "/YYYY",
                      "YYYY/",
                      "-MM-YYYY",
                      "YYYY-MM-",
                      "-YYYY-MM",
                      "MM-YYYY-",
                      "-YYYY",
                      "YYYY-"
                    ],
                    "example": "/MM/YYYY"
                  },
                  "documentSymbols": {
                    "type": "object",
                    "description": "Prefiksy numerów per typ dokumentu; brakujący klucz = pusty prefiks.",
                    "properties": {
                      "Faktura": {
                        "type": "string",
                        "example": "F"
                      },
                      "FakturaVAT": {
                        "type": "string",
                        "example": "FV/"
                      },
                      "FakturaZaliczka": {
                        "type": "string",
                        "example": "FZ/"
                      },
                      "FakturaKorygujaca": {
                        "type": "string",
                        "example": "KOR/"
                      },
                      "FakturaKorygujacaZaliczkowa": {
                        "type": "string"
                      },
                      "FakturaKorygujacaRozliczeniowa": {
                        "type": "string"
                      },
                      "FakturaRozliczeniowa": {
                        "type": "string",
                        "example": "FK/"
                      },
                      "FakturaProforma": {
                        "type": "string",
                        "example": "FP/"
                      },
                      "FakturaProformaBezVAT": {
                        "type": "string"
                      },
                      "Zamowienie": {
                        "type": "string",
                        "example": "ZAM/"
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "KsefConnectionResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "isAuthorized": {
                    "type": "boolean",
                    "example": true,
                    "description": "Czy ostatnia autoryzacja w KSeF się powiodła."
                  },
                  "hasToken": {
                    "type": "boolean",
                    "example": true,
                    "description": "Czy na koncie zapisany jest token KSeF."
                  },
                  "hasCertificate": {
                    "type": "boolean",
                    "example": false,
                    "description": "Czy na koncie zapisany jest certyfikat KSeF."
                  },
                  "hasConnectionConfig": {
                    "type": "boolean",
                    "example": true,
                    "description": "Czy połączenie jest skonfigurowane: zapisany token KSeF albo certyfikat (hasToken lub hasCertificate)."
                  },
                  "connectionType": {
                    "type": "string",
                    "enum": [
                      "TOKEN",
                      "CERTIFICATE"
                    ],
                    "example": "TOKEN",
                    "description": "Metoda połączenia: token KSeF (TOKEN) albo certyfikat (CERTIFICATE). Gdy konto nie ma jeszcze połączenia: CERTIFICATE."
                  },
                  "lastCheckAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": "2026-09-26T10:30:00.000Z"
                  },
                  "lastError": {
                    "type": "string",
                    "nullable": true
                  },
                  "lastErrorAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": "2026-09-26T10:30:00.000Z"
                  },
                  "environment": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                      "prod",
                      "test",
                      "demo",
                      null
                    ],
                    "example": "prod"
                  },
                  "nip": {
                    "type": "string",
                    "nullable": true,
                    "example": "5261040828"
                  },
                  "permissions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "example": [
                      "InvoiceWrite",
                      "InvoiceRead"
                    ]
                  },
                  "certificateExpiresAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": "2026-09-26T10:30:00.000Z",
                    "description": "Data ważności certyfikatu. Null dla połączenia tokenem."
                  }
                }
              }
            }
          }
        ]
      },
      "KsefConnectionInput": {
        "type": "object",
        "description": "Połączenie z KSeF jedną z dwóch metod. Token: connectionType=TOKEN i token. Certyfikat: connectionType=CERTIFICATE oraz certificateContent, privateKeyContent i privateKeyPassword. Gdy connectionType jest pominięty, a w treści są pola certyfikatu, połączenie jest zapisywane jako certyfikat. Zapis jednej metody zastępuje drugą.",
        "properties": {
          "connectionType": {
            "type": "string",
            "enum": [
              "TOKEN",
              "CERTIFICATE"
            ],
            "description": "Metoda połączenia: TOKEN (token KSeF) albo CERTIFICATE (certyfikat KSeF). Pominięty: CERTIFICATE, gdy podano pola certyfikatu, w przeciwnym razie TOKEN.",
            "example": "TOKEN"
          },
          "token": {
            "type": "string",
            "description": "Token KSeF wygenerowany w Aplikacji Podatnika KSeF, z uprawnieniami do wystawiania i przeglądania faktur. Wymagany dla connectionType=TOKEN. Białe znaki (spacje, znaki nowej linii) są usuwane."
          },
          "certificateContent": {
            "type": "string",
            "description": "Certyfikat KSeF w formacie PEM. Wymagany dla connectionType=CERTIFICATE."
          },
          "privateKeyContent": {
            "type": "string",
            "description": "Klucz prywatny w formacie PEM (może być zaszyfrowany). Wymagany dla connectionType=CERTIFICATE."
          },
          "privateKeyPassword": {
            "type": "string",
            "description": "Hasło do klucza prywatnego. Wymagane dla connectionType=CERTIFICATE."
          },
          "environment": {
            "type": "string",
            "enum": [
              "prod",
              "test",
              "demo"
            ],
            "description": "Środowisko KSeF. W sandboxie używaj test.",
            "example": "test"
          }
        }
      },
      "KsefConnectionSavedResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "KSeF token connection saved."
              },
              "data": {
                "type": "object",
                "properties": {
                  "environment": {
                    "type": "string",
                    "enum": [
                      "prod",
                      "test",
                      "demo"
                    ],
                    "example": "test"
                  },
                  "connectionType": {
                    "type": "string",
                    "enum": [
                      "TOKEN",
                      "CERTIFICATE"
                    ],
                    "example": "TOKEN"
                  },
                  "certificateFingerprint": {
                    "type": "string",
                    "example": "a1b2c3d4e5f60718293a4b5c6d7e8f9012345678",
                    "description": "Odcisk SHA-1 certyfikatu. Tylko dla connectionType=CERTIFICATE."
                  },
                  "certificateExpiresAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": "2026-09-26T10:30:00.000Z",
                    "description": "Data ważności certyfikatu. Tylko dla connectionType=CERTIFICATE."
                  }
                }
              }
            }
          }
        ]
      },
      "KsefConnectionTestResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "KSeF connection test passed."
              },
              "data": {
                "type": "object",
                "properties": {
                  "isAuthorized": {
                    "type": "boolean",
                    "example": true
                  },
                  "environment": {
                    "type": "string",
                    "example": "test"
                  },
                  "permissions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "lastError": {
                    "type": "string",
                    "nullable": true
                  },
                  "checkedAt": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "example": "2026-09-26T10:30:00.000Z"
                  }
                }
              }
            }
          }
        ]
      },
      "KsefConnectionDeletedResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "KSeF connection deactivated."
              },
              "data": {
                "type": "object",
                "properties": {
                  "isAuthorized": {
                    "type": "boolean",
                    "example": false
                  },
                  "hasConnectionConfig": {
                    "type": "boolean",
                    "example": false
                  }
                }
              }
            }
          }
        ]
      },
      "AuthMeResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "clientId": {
                    "type": "string",
                    "nullable": true,
                    "example": "client_5c62e06900bcbeb2f39a78ac45ed45f5"
                  },
                  "name": {
                    "type": "string",
                    "example": "Integracja z e-Sklepem"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "example": [
                      "documents:read",
                      "clients:browse"
                    ]
                  },
                  "userId": {
                    "type": "string",
                    "example": "507f1f77bcf86cd799439012"
                  }
                }
              }
            }
          }
        ]
      },
      "CompanyLookupResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "company": {
                    "type": "object",
                    "properties": {
                      "nip": {
                        "type": "string",
                        "example": "5261040828"
                      },
                      "name": {
                        "type": "string",
                        "example": "ACME SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ"
                      },
                      "regon": {
                        "type": "string",
                        "example": "146000000"
                      },
                      "street": {
                        "type": "string",
                        "example": "ul. Marszałkowska 1 lok. 2"
                      },
                      "postcode": {
                        "type": "string",
                        "example": "00-001"
                      },
                      "postalCode": {
                        "type": "string",
                        "example": "00-001",
                        "description": "Kod pocztowy (ta sama wartość co postcode; nazwa pola jak w kontrahencie)."
                      },
                      "city": {
                        "type": "string",
                        "example": "Warszawa"
                      },
                      "country": {
                        "type": "string",
                        "example": "Polska"
                      },
                      "countryCode": {
                        "type": "string",
                        "example": "PL"
                      }
                    }
                  },
                  "buyer": {
                    "type": "object",
                    "description": "Te same dane z nazwami pól kontrahenta: gotowe jako buyer dokumentu (POST /documents) albo body nowego kontrahenta (POST /clients).",
                    "properties": {
                      "type": {
                        "type": "string",
                        "example": "company"
                      },
                      "identifierType": {
                        "type": "string",
                        "example": "nip"
                      },
                      "nip": {
                        "type": "string",
                        "example": "5261040828"
                      },
                      "name": {
                        "type": "string",
                        "example": "ACME SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ"
                      },
                      "regon": {
                        "type": "string",
                        "example": "146000000"
                      },
                      "street": {
                        "type": "string",
                        "example": "ul. Marszałkowska 1 lok. 2"
                      },
                      "postalCode": {
                        "type": "string",
                        "example": "00-001"
                      },
                      "city": {
                        "type": "string",
                        "example": "Warszawa"
                      },
                      "country": {
                        "type": "string",
                        "example": "Polska"
                      },
                      "countryCode": {
                        "type": "string",
                        "example": "PL"
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "WarehouseDocumentRequestBody": {
        "type": "object",
        "required": [
          "documentType",
          "issueDate",
          "products"
        ],
        "properties": {
          "documentType": {
            "type": "string",
            "enum": [
              "WZ",
              "PZ",
              "PW",
              "RW",
              "MM"
            ],
            "description": "WZ wydanie zewnętrzne (do odbiorcy), PZ przyjęcie zewnętrzne (od dostawcy), PW przychód wewnętrzny, RW rozchód wewnętrzny, MM przesunięcie między magazynami.",
            "example": "PZ"
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "example": "2026-09-26",
            "description": "Data wystawienia (RRRR-MM-DD)."
          },
          "subDate": {
            "type": "string",
            "format": "date",
            "description": "WZ: data wydania towaru, PZ: data otrzymania towaru. Domyślnie data wystawienia. PW/RW/MM jej nie mają."
          },
          "warehouseId": {
            "type": "string",
            "description": "Magazyn dokumentu (WZ, PZ, PW, RW). Domyślnie magazyn domyślny konta."
          },
          "sourceWarehouseId": {
            "type": "string",
            "description": "MM: magazyn źródłowy. Domyślnie magazyn domyślny konta."
          },
          "targetWarehouseId": {
            "type": "string",
            "description": "MM: magazyn docelowy (wymagany, inny niż źródłowy)."
          },
          "buyerId": {
            "type": "string",
            "description": "WZ: odbiorca, PZ: dostawca (ID kontrahenta). Nie dotyczy PW/RW/MM."
          },
          "buyer": {
            "$ref": "#/components/schemas/ClientReference",
            "description": "Kontrahent podany danymi zamiast buyerId (dopasowanie po NIP, w przeciwnym razie nowy kontrahent)."
          },
          "products": {
            "type": "array",
            "maxItems": 500,
            "description": "Pozycje z kartoteki produktów. Nazwa, jednostka i cena z kartoteki, jeśli ich nie podasz.",
            "items": {
              "type": "object",
              "required": [
                "productId",
                "quantity"
              ],
              "properties": {
                "productId": {
                  "type": "string",
                  "example": "681a3b2c4d5e6f7a8b9c0d1e",
                  "description": "ID produktu z kartoteki (browseProducts). Na ten produkt księgowany jest ruch magazynowy."
                },
                "quantity": {
                  "type": "number",
                  "minimum": 0,
                  "exclusiveMinimum": true,
                  "example": 20,
                  "description": "Ilość (większa od 0)."
                },
                "netPrice": {
                  "type": "number",
                  "minimum": 0,
                  "example": 45.5,
                  "description": "Cena jednostkowa netto. Domyślnie PZ/PW: cena zakupu z kartoteki, WZ/RW/MM: cena sprzedaży netto."
                },
                "name": {
                  "type": "string",
                  "description": "Nazwa na dokumencie (domyślnie z kartoteki)."
                },
                "unitOfMeasure": {
                  "type": "string",
                  "description": "Jednostka (domyślnie z kartoteki)."
                }
              }
            }
          },
          "sourceInvoiceId": {
            "type": "string",
            "description": "WZ do faktury sprzedaży: dokumenty zostają powiązane w obie strony, a numer WZ trafia na fakturę. Bez buyerId odbiorca jest brany z faktury."
          },
          "stockStatus": {
            "type": "string",
            "enum": [
              "posted",
              "pending"
            ],
            "description": "posted = ruch od razu; pending = do potwierdzenia wydania/przyjęcia w aplikacji (towar tylko zarezerwowany). Domyślnie z ustawienia „potwierdzanie wydań”."
          },
          "allowNegativeStock": {
            "type": "boolean",
            "description": "true = wystaw WZ/RW/MM mimo braku towaru (stan zejdzie poniżej zera). Domyślnie brak towaru odrzuca dokument (422 STOCK_SHORTAGE)."
          },
          "issuePlace": {
            "type": "string",
            "description": "Miejsce wystawienia (domyślnie z ustawień konta albo miasto z adresu firmy)."
          },
          "comments": {
            "type": "string",
            "description": "Uwagi (domyślnie uwagi z ustawień konta)."
          },
          "signatures": {
            "type": "object",
            "description": "Pola podpisów na PDF. Domyślnie z ustawienia podpisów dokumentów magazynowych (wystawia: imię i nazwisko właściciela albo pracownika).",
            "properties": {
              "issuerSignature": {
                "type": "object",
                "properties": {
                  "show": {
                    "type": "boolean"
                  },
                  "value": {
                    "type": "string"
                  }
                }
              },
              "receiverSignature": {
                "type": "object",
                "properties": {
                  "show": {
                    "type": "boolean"
                  },
                  "value": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "useAccountDefaults": {
            "type": "boolean",
            "description": "false = bez wartości domyślnych z ustawień konta (miejsce, uwagi, podpisy).",
            "example": true
          }
        }
      },
      "WarehouseDocumentExternal": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "documentType": {
            "type": "string",
            "example": "PZ"
          },
          "documentNumber": {
            "type": "string",
            "example": "PZ/4/09/2026"
          },
          "invoiceName": {
            "type": "string",
            "example": "Przyjęcie zewnętrzne PZ/4/09/2026"
          },
          "issueDate": {
            "type": "string",
            "example": "2026-09-26"
          },
          "warehouseId": {
            "type": "string",
            "nullable": true
          },
          "warehouseName": {
            "type": "string",
            "nullable": true
          },
          "sourceWarehouseId": {
            "type": "string",
            "nullable": true
          },
          "sourceWarehouseName": {
            "type": "string",
            "nullable": true
          },
          "targetWarehouseId": {
            "type": "string",
            "nullable": true
          },
          "targetWarehouseName": {
            "type": "string",
            "nullable": true
          },
          "stockStatus": {
            "type": "string",
            "enum": [
              "posted",
              "pending"
            ],
            "example": "posted"
          },
          "contractor": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Odbiorca (WZ) albo dostawca (PZ); null dla PW/RW/MM."
          },
          "netSum": {
            "type": "number",
            "example": 910
          },
          "products": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "productId": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "unitOfMeasure": {
                  "type": "string"
                },
                "quantity": {
                  "type": "number"
                },
                "netPrice": {
                  "type": "number"
                },
                "netValue": {
                  "type": "number"
                }
              }
            }
          },
          "sourceInvoiceId": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WarehouseDocumentPreview": {
        "type": "object",
        "properties": {
          "documentType": {
            "type": "string",
            "example": "PZ"
          },
          "documentNo": {
            "type": "integer",
            "example": 4
          },
          "documentNumber": {
            "type": "string",
            "example": "PZ/4/09/2026"
          },
          "issueDate": {
            "type": "string",
            "example": "2026-09-26"
          },
          "subDate": {
            "type": "string",
            "nullable": true,
            "example": "2026-09-26"
          },
          "subDateLabel": {
            "type": "string",
            "nullable": true,
            "example": "Data otrzymania towaru"
          },
          "warehouse": {
            "type": "object",
            "nullable": true,
            "properties": {
              "id": {
                "type": "string",
                "example": "681a3b2c4d5e6f7a8b9c0d1f"
              },
              "name": {
                "type": "string",
                "example": "Magazyn główny"
              }
            }
          },
          "sourceWarehouse": {
            "type": "object",
            "nullable": true,
            "properties": {
              "id": {
                "type": "string",
                "example": "681a3b2c4d5e6f7a8b9c0d1f"
              },
              "name": {
                "type": "string",
                "example": "Magazyn główny"
              }
            }
          },
          "targetWarehouse": {
            "type": "object",
            "nullable": true,
            "properties": {
              "id": {
                "type": "string",
                "example": "681a3b2c4d5e6f7a8b9c0d1f"
              },
              "name": {
                "type": "string",
                "example": "Magazyn główny"
              }
            }
          },
          "contractor": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "productId": {
                  "type": "string",
                  "example": "681a3b2c4d5e6f7a8b9c0d1e"
                },
                "name": {
                  "type": "string",
                  "example": "Krzesło biurowe"
                },
                "unitOfMeasure": {
                  "type": "string",
                  "example": "szt."
                },
                "quantity": {
                  "type": "number",
                  "example": 20
                },
                "netPrice": {
                  "type": "number",
                  "example": 45.5
                },
                "netValue": {
                  "type": "number",
                  "example": 910
                },
                "productType": {
                  "type": "string",
                  "nullable": true,
                  "example": "goods",
                  "description": "Rodzaj pozycji w kartotece (goods = towar). Usługa na dokumencie magazynowym zostaje oznaczona jako towar."
                },
                "stockBefore": {
                  "type": "number",
                  "example": 5,
                  "description": "Stan w magazynie dokumentu (MM: w źródłowym) przed dokumentem."
                },
                "stockAfter": {
                  "type": "number",
                  "example": 25,
                  "description": "Stan po dokumencie."
                },
                "targetStockBefore": {
                  "type": "number",
                  "description": "MM: stan w magazynie docelowym przed dokumentem."
                },
                "targetStockAfter": {
                  "type": "number",
                  "description": "MM: stan w magazynie docelowym po dokumencie."
                }
              }
            }
          },
          "totals": {
            "type": "object",
            "properties": {
              "netSum": {
                "type": "number",
                "example": 910
              },
              "vatSum": {
                "type": "number",
                "example": 209.3
              },
              "grossSum": {
                "type": "number",
                "example": 1119.3
              }
            }
          },
          "stockStatus": {
            "type": "string",
            "enum": [
              "posted",
              "pending"
            ],
            "example": "posted"
          },
          "shortages": {
            "type": "array",
            "description": "Braki towaru dla WZ/RW/MM (stan minus rezerwacje innych dokumentów oczekujących). Niepusta lista odrzuci wystawienie bez allowNegativeStock.",
            "items": {
              "type": "object",
              "properties": {
                "productId": {
                  "type": "string"
                },
                "productName": {
                  "type": "string"
                },
                "requested": {
                  "type": "number"
                },
                "available": {
                  "type": "number"
                },
                "shortage": {
                  "type": "number"
                }
              }
            }
          },
          "sourceInvoice": {
            "type": "object",
            "nullable": true,
            "properties": {
              "id": {
                "type": "string"
              },
              "documentNumber": {
                "type": "string"
              }
            }
          },
          "issuePlace": {
            "type": "string",
            "example": "Kraków"
          },
          "comments": {
            "type": "string",
            "example": ""
          },
          "signatures": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          },
          "appliedDefaults": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "example": "ISSUE_PLACE"
                },
                "field": {
                  "type": "string",
                  "example": "issuePlace"
                },
                "message": {
                  "type": "string",
                  "example": "Miejsce wystawienia Kraków z ustawień konta."
                }
              }
            },
            "description": "Wartości uzupełnione automatycznie (ustawienia konta, magazyn domyślny, odbiorca z faktury)."
          }
        }
      },
      "WarehouseDocumentResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "Utworzono dokument Przyjęcie zewnętrzne PZ/4/09/2026."
              },
              "data": {
                "type": "object",
                "properties": {
                  "document": {
                    "$ref": "#/components/schemas/WarehouseDocumentExternal"
                  },
                  "preview": {
                    "$ref": "#/components/schemas/WarehouseDocumentPreview"
                  }
                }
              }
            }
          }
        ]
      },
      "WarehouseDocumentPreviewResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "preview": {
                    "$ref": "#/components/schemas/WarehouseDocumentPreview"
                  },
                  "valid": {
                    "type": "boolean",
                    "example": true
                  }
                }
              }
            }
          }
        ]
      },
      "WebhookExternal": {
        "type": "object",
        "description": "Webhook zarejestrowany na koncie. Sekret podpisujący nie jest zwracany.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "endpoint": {
            "type": "string",
            "nullable": true,
            "example": "https://erp.example.com/hooks/fakturnia"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "example": "ERP"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "client.created",
                "client.updated",
                "client.deleted",
                "product.created",
                "product.updated",
                "product.deleted",
                "document.created",
                "document.updated",
                "document.deleted",
                "document.sentToKSeF",
                "document.ksefRejected",
                "document.paymentStatusChanged",
                "document.ksefImported"
              ]
            },
            "example": [
              "document.created",
              "document.sentToKSeF"
            ]
          },
          "status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "ACTIVE",
              "INACTIVE",
              "ERROR",
              null
            ],
            "example": "ACTIVE",
            "description": "ERROR = wyłączony automatycznie po 10 kolejnych niepowodzeniach; włącz ponownie przez PATCH status=ACTIVE."
          },
          "successCount": {
            "type": "integer",
            "example": 128
          },
          "failureCount": {
            "type": "integer",
            "example": 2
          },
          "consecutiveFailures": {
            "type": "integer",
            "example": 0
          },
          "lastDeliveryAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "description": "Jedna dostawa zdarzenia (z ponowieniami). `id` to wartość z nagłówka X-Webhook-Delivery i pola `id` w treści.",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "event": {
            "type": "string",
            "nullable": true,
            "enum": [
              "client.created",
              "client.updated",
              "client.deleted",
              "product.created",
              "product.updated",
              "product.deleted",
              "document.created",
              "document.updated",
              "document.deleted",
              "document.sentToKSeF",
              "document.ksefRejected",
              "document.paymentStatusChanged",
              "document.ksefImported",
              "webhook.test",
              null
            ],
            "example": "document.created"
          },
          "resourceId": {
            "type": "string",
            "nullable": true,
            "example": "681a3b2c4d5e6f7a8b9c0d1f"
          },
          "status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "PENDING",
              "SUCCESS",
              "FAILED",
              "CANCELLED",
              null
            ],
            "example": "SUCCESS"
          },
          "attempts": {
            "type": "integer",
            "example": 1
          },
          "nextAttemptAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z",
            "description": "Termin kolejnej próby (dla PENDING)."
          },
          "lastAttemptAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          },
          "lastError": {
            "type": "string",
            "nullable": true,
            "example": null
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-26T10:30:00.000Z"
          }
        }
      },
      "WebhookInput": {
        "type": "object",
        "required": [
          "endpoint",
          "events"
        ],
        "properties": {
          "endpoint": {
            "type": "string",
            "format": "uri",
            "example": "https://erp.example.com/hooks/fakturnia",
            "description": "Publiczny adres HTTPS. Adresy prywatne, lokalne i nie-HTTP są odrzucane."
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "client.created",
                "client.updated",
                "client.deleted",
                "product.created",
                "product.updated",
                "product.deleted",
                "document.created",
                "document.updated",
                "document.deleted",
                "document.sentToKSeF",
                "document.ksefRejected",
                "document.paymentStatusChanged",
                "document.ksefImported"
              ]
            },
            "description": "Zdarzenia do subskrypcji (lista w opisie API)."
          },
          "description": {
            "type": "string",
            "maxLength": 200,
            "example": "ERP"
          }
        }
      },
      "WebhookPatchInput": {
        "type": "object",
        "description": "Aktualizacja częściowa: zmieniają się tylko przesłane klucze.",
        "properties": {
          "endpoint": {
            "type": "string",
            "format": "uri",
            "example": "https://erp.example.com/hooks/fakturnia"
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "client.created",
                "client.updated",
                "client.deleted",
                "product.created",
                "product.updated",
                "product.deleted",
                "document.created",
                "document.updated",
                "document.deleted",
                "document.sentToKSeF",
                "document.ksefRejected",
                "document.paymentStatusChanged",
                "document.ksefImported"
              ]
            },
            "description": "Zastępuje całą listę subskrypcji."
          },
          "description": {
            "type": "string",
            "maxLength": 200
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ],
            "description": "ACTIVE włącza (także po automatycznym wyłączeniu), INACTIVE wstrzymuje dostawy."
          }
        }
      },
      "InitialWebhookInput": {
        "type": "object",
        "required": [
          "endpoint"
        ],
        "properties": {
          "endpoint": {
            "type": "string",
            "format": "uri",
            "example": "https://shop.example.com/wp-json/fakturnia/v1/webhook"
          },
          "siteName": {
            "type": "string",
            "example": "Sklep Example"
          },
          "domain": {
            "type": "string",
            "example": "shop.example.com"
          },
          "rotateSecret": {
            "type": "boolean",
            "example": false,
            "description": "Gdy webhook już istnieje: wygeneruj i zwróć nowy sekret."
          }
        }
      },
      "WebhookResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "webhook": {
                    "$ref": "#/components/schemas/WebhookExternal"
                  }
                }
              }
            }
          }
        ]
      },
      "WebhookCreatedResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "Webhook created."
              },
              "data": {
                "type": "object",
                "properties": {
                  "webhook": {
                    "$ref": "#/components/schemas/WebhookExternal"
                  },
                  "secret": {
                    "type": "string",
                    "example": "9f2a7c1d4e6b8a0c3d5f7e9b1a2c4d6e8f0a1b3c5d7e9f2a4b6c8d0e1f3a5b7c",
                    "description": "Sekret do weryfikacji X-Webhook-Signature. Pokazywany tylko w tej odpowiedzi."
                  }
                }
              }
            }
          }
        ]
      },
      "WebhookListResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "webhooks": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/WebhookExternal"
                    }
                  },
                  "hasInitialWebhook": {
                    "type": "boolean",
                    "example": true,
                    "description": "Czy istnieje webhook dla adresu z parametru endpoint (false bez parametru)."
                  },
                  "initialWebhookId": {
                    "type": "string",
                    "nullable": true,
                    "example": "681a3b2c4d5e6f7a8b9c0d1e"
                  }
                }
              }
            }
          }
        ]
      },
      "InitialWebhookResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "Initial webhook created."
              },
              "data": {
                "type": "object",
                "properties": {
                  "created": {
                    "type": "boolean",
                    "example": true
                  },
                  "rotated": {
                    "type": "boolean",
                    "example": false
                  },
                  "webhook": {
                    "$ref": "#/components/schemas/WebhookExternal"
                  },
                  "secret": {
                    "type": "string",
                    "example": "9f2a7c1d4e6b8a0c3d5f7e9b1a2c4d6e8f0a1b3c5d7e9f2a4b6c8d0e1f3a5b7c",
                    "description": "Obecny tylko przy utworzeniu albo rotacji."
                  }
                }
              }
            }
          }
        ]
      },
      "WebhookSecretResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "Webhook secret rotated."
              },
              "data": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "681a3b2c4d5e6f7a8b9c0d1e"
                  },
                  "secret": {
                    "type": "string",
                    "example": "9f2a7c1d4e6b8a0c3d5f7e9b1a2c4d6e8f0a1b3c5d7e9f2a4b6c8d0e1f3a5b7c",
                    "description": "Nowy sekret. Pokazywany tylko w tej odpowiedzi."
                  }
                }
              }
            }
          }
        ]
      },
      "WebhookDeliveriesResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "deliveries": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/WebhookDelivery"
                    }
                  },
                  "currentPage": {
                    "type": "integer",
                    "example": 1,
                    "description": "Numer bieżącej strony (od 1)."
                  },
                  "totalPages": {
                    "type": "integer",
                    "example": 5,
                    "description": "Liczba stron."
                  },
                  "totalCount": {
                    "type": "integer",
                    "example": 50,
                    "description": "Liczba wszystkich pasujących rekordów."
                  },
                  "itemsPerPage": {
                    "type": "integer",
                    "example": 10,
                    "description": "Rozmiar strony (maks. 100)."
                  },
                  "searchQuery": {
                    "type": "string",
                    "example": "",
                    "description": "Użyty filtr tekstowy (pusty, gdy brak)."
                  }
                }
              }
            }
          }
        ]
      },
      "WebhookTestResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/SuccessResponse"
          },
          {
            "type": "object",
            "properties": {
              "message": {
                "type": "string",
                "nullable": true,
                "example": "Test delivery succeeded."
              },
              "data": {
                "type": "object",
                "properties": {
                  "delivery": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "example": "681a3b2c4d5e6f7a8b9c0d1e"
                      },
                      "ok": {
                        "type": "boolean",
                        "example": true,
                        "description": "true, gdy endpoint odpowiedział 2xx."
                      },
                      "statusCode": {
                        "type": "integer",
                        "example": 200,
                        "description": "Kod HTTP odpowiedzi endpointu (500 przy błędzie sieci)."
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "SUCCESS",
                          "FAILED"
                        ],
                        "example": "SUCCESS"
                      },
                      "lastError": {
                        "type": "string",
                        "nullable": true,
                        "example": null
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "WebhookEventPayload": {
        "type": "object",
        "description": "Treść żądania POST, które Fakturnia wysyła na Twój endpoint. Podpis HMAC-SHA256 (nagłówek X-Webhook-Signature) liczony jest z dokładnie tych bajtów.",
        "required": [
          "id",
          "event",
          "timestamp",
          "data",
          "resourceId"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "681a3b2c4d5e6f7a8b9c0d1e",
            "description": "Identyfikator dostawy: ten sam przy każdym ponowieniu, użyj go do deduplikacji. Powtórzony w nagłówku X-Webhook-Delivery."
          },
          "event": {
            "type": "string",
            "enum": [
              "client.created",
              "client.updated",
              "client.deleted",
              "product.created",
              "product.updated",
              "product.deleted",
              "document.created",
              "document.updated",
              "document.deleted",
              "document.sentToKSeF",
              "document.ksefRejected",
              "document.paymentStatusChanged",
              "document.ksefImported",
              "webhook.test"
            ],
            "example": "document.created"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-26T10:30:00.000Z",
            "description": "Moment zdarzenia (UTC)."
          },
          "data": {
            "type": "object",
            "description": "Identyfikator zasobu nazwany po typie: documentId, clientId, productId albo webhookId; przy zdarzeniach zbiorczych także lista (documentIds, clientIds, productIds).",
            "properties": {
              "documentId": {
                "type": "string",
                "example": "681a3b2c4d5e6f7a8b9c0d1f"
              },
              "documentIds": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "clientId": {
                "type": "string"
              },
              "clientIds": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "productId": {
                "type": "string"
              },
              "productIds": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "webhookId": {
                "type": "string"
              }
            }
          },
          "resourceId": {
            "type": "string",
            "example": "681a3b2c4d5e6f7a8b9c0d1f",
            "description": "Identyfikator zasobu (to samo co w data, zachowane dla starszych odbiorców)."
          },
          "resourceIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tylko przy zdarzeniach zbiorczych."
          }
        }
      },
      "UpdateDocumentRequestBody": {
        "type": "object",
        "required": [
          "issueDate"
        ],
        "description": "Pełna aktualizacja (PUT): pominięte pola opcjonalne są czyszczone. Typ dokumentu nie zmienia się.",
        "properties": {
          "correctionAdvanceAmountAfter": {
            "type": "number",
            "description": "Kwota zaliczki PO korekcie (FakturaKorygujacaZaliczkowa)."
          },
          "correctionSettlementAmountAfter": {
            "type": "number",
            "description": "Kwota rozliczenia PO korekcie (FakturaKorygujacaRozliczeniowa)."
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "description": "Data wystawienia (ISO 8601)",
            "example": "2026-05-07"
          },
          "documentNo": {
            "type": "integer",
            "minimum": 1,
            "description": "Opcjonalny numer dokumentu. Jeśli podany, zostanie użyty zamiast automatycznej numeracji.",
            "example": 1
          },
          "numberingFormat": {
            "type": "string",
            "enum": [
              "/MM/YYYY",
              "YYYY/MM/",
              "/YYYY/MM",
              "MM/YYYY/",
              "/YYYY",
              "YYYY/",
              "-MM-YYYY",
              "YYYY-MM-",
              "-YYYY-MM",
              "MM-YYYY-",
              "-YYYY",
              "YYYY-"
            ],
            "description": "Format numeracji (np. \"/MM/YYYY\"). Domyślnie z ustawień użytkownika.",
            "example": "/MM/YYYY"
          },
          "symbol": {
            "type": "string",
            "description": "Prefiks symbolu dokumentu (np. \"FV/\"). Domyślnie z ustawień.",
            "example": "FV/"
          },
          "documentNumber": {
            "type": "string",
            "description": "Pełny numer dokumentu do walidacji 1:1. Jeśli podany razem z documentNo, musi być spójny.",
            "example": "FV/1/05/2026"
          },
          "invoiceName": {
            "type": "string",
            "description": "Nazwa faktury (np. dla FV zaliczkowych)",
            "example": "Faktura zaliczkowa"
          },
          "buyerId": {
            "type": "string",
            "description": "ID istniejącego klienta w systemie. Nie stosować razem z buyer. Wymagane buyerId albo buyer (poza korektą, która przejmuje nabywcę z korygowanej faktury).",
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "buyer": {
            "$ref": "#/components/schemas/ClientReference"
          },
          "receiverId": {
            "type": "string",
            "description": "ID opcjonalnego odbiorcy (dla faktur z wieloma stronami)."
          },
          "receiver": {
            "$ref": "#/components/schemas/ClientReference"
          },
          "products": {
            "type": "array",
            "description": "Pozycje dokumentu. Korekty: pełna lista pozycji PO korekcie (sumy dokumentu to różnica względem korygowanej faktury). FakturaZaliczka: pomiń, pozycje to rozkład zaliczki na stawki VAT zamówienia.",
            "items": {
              "type": "object",
              "required": [
                "name",
                "unitOfMeasure",
                "quantity"
              ],
              "properties": {
                "name": {
                  "type": "string",
                  "example": "Usługa programistyczna"
                },
                "gtu": {
                  "type": "string",
                  "nullable": true,
                  "enum": [
                    "GTU_01",
                    "GTU_02",
                    "GTU_03",
                    "GTU_04",
                    "GTU_05",
                    "GTU_06",
                    "GTU_07",
                    "GTU_08",
                    "GTU_09",
                    "GTU_10",
                    "GTU_11",
                    "GTU_12",
                    "GTU_13",
                    null
                  ],
                  "description": "Kod GTU (opcjonalny)"
                },
                "pkwiu": {
                  "type": "string",
                  "nullable": true
                },
                "unitOfMeasure": {
                  "type": "string",
                  "example": "szt."
                },
                "quantity": {
                  "type": "number",
                  "example": 1
                },
                "netPrice": {
                  "type": "number",
                  "nullable": true,
                  "description": "Cena jednostkowa netto. Gdy podana, wartości netValue/amountOfVat/grossValue są wyliczane automatycznie.",
                  "example": 100
                },
                "grossPrice": {
                  "type": "number",
                  "nullable": true,
                  "description": "Cena jednostkowa brutto (alternatywa dla netPrice).",
                  "example": 123
                },
                "netValue": {
                  "type": "number",
                  "nullable": true,
                  "description": "Opcjonalne, wartości mogą zostać przeliczone automatycznie.",
                  "example": 100
                },
                "grossValue": {
                  "type": "number",
                  "nullable": true,
                  "description": "Opcjonalne, wartości mogą zostać przeliczone automatycznie.",
                  "example": 123
                },
                "amountOfVat": {
                  "type": "number",
                  "nullable": true,
                  "description": "Opcjonalne, wartości mogą zostać przeliczone automatycznie.",
                  "example": 23
                },
                "vatRate": {
                  "oneOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "string"
                    }
                  ],
                  "example": 23,
                  "description": "Stawka VAT zgodna ze słownikiem AppData.VatRates. Wartość jest walidowana, a taxSymbol generowany automatycznie. Brak = domyślna stawka konta (settings.defaultTaxRate). \"marza\" = pozycja w procedurze marży (art. 119 i 120 ustawy o VAT): podaj grossPrice, faktura pokazuje tylko kwoty brutto, w KSeF suma trafia do P_13_11; wymaga annotations.marginProcedure (inaczej 422 MARGIN_LINE_WITHOUT_PROCEDURE)."
                },
                "marginPurchaseValue": {
                  "type": "number",
                  "nullable": true,
                  "minimum": 0,
                  "description": "Tylko vatRate \"marza\": kwota nabycia całej pozycji brutto w PLN (towar używany: cena zakupu; biuro podróży: koszty usług nabytych dla turysty). Nie trafia na fakturę ani do KSeF; służy do marży i VAT od marży w rejestrze VAT i JPK. Brak = do uzupełnienia później. W korekcie pominięta: przejmowana z korygowanej pozycji o tej nazwie, proporcjonalnie do ilości.",
                  "example": 3000
                },
                "marginTaxRate": {
                  "type": "number",
                  "nullable": true,
                  "enum": [
                    23,
                    8,
                    5,
                    0,
                    null
                  ],
                  "description": "Tylko vatRate \"marza\": stawka VAT liczona od marży (VAT = marża × stawka / (100 + stawka); ujemna marża = VAT 0). Domyślnie 23.",
                  "example": 23
                },
                "discount": {
                  "type": "number",
                  "example": 0
                },
                "currency": {
                  "type": "string",
                  "example": "PLN"
                }
              }
            }
          },
          "useAccountDefaults": {
            "type": "boolean",
            "description": "Domyślnie true: brakujące pola dostają wartości z ustawień konta jak nowy dokument w aplikacji (uwagi, podpisy, miejsce wystawienia, automatyczne adnotacje MPP/marża z rachunkiem VAT, podstawa zwolnienia dla stawki zw, forma i status płatności, stawka VAT pozycji). Pole podane jawnie zawsze wygrywa. false = bez wartości domyślnych konta. Korekta i tak przejmuje nabywcę, odbiorcę, walutę i adnotacje z korygowanej faktury, jeśli ich nie podasz.",
            "example": true
          },
          "currency": {
            "type": "string",
            "description": "Waluta dokumentu (ISO 4217)",
            "example": "PLN"
          },
          "exchangeRate": {
            "type": "number",
            "description": "Kurs wymiany dla walut obcych"
          },
          "issuePlace": {
            "type": "string",
            "description": "Miejsce wystawienia",
            "example": "Warszawa"
          },
          "comments": {
            "type": "string",
            "description": "Uwagi do dokumentu"
          },
          "paymentDescription": {
            "type": "string",
            "description": "Opis płatności"
          },
          "showPaymentSection": {
            "type": "boolean",
            "description": "Czy pokazywać sekcję płatności na dokumencie/PDF. Dla Zamowienie można ustawić false."
          },
          "paymentDeadlineDate": {
            "type": "string",
            "format": "date",
            "description": "Termin płatności (wymagany gdy paymentStatusId=1). Przy statusie Zapłacono jest ignorowany."
          },
          "additionalPaymentDate": {
            "type": "string",
            "format": "date",
            "description": "Data otrzymania zapłaty (wymagana gdy paymentStatusId=0). Przy statusie Do zapłaty jest ignorowana."
          },
          "additionalPaymentDateHeaderId": {
            "type": "number",
            "description": "ID nagłówka daty płatności ze słownika paymentDateHeaders. Dla paymentStatusId=0 domyślnie ustawiane jest id=2 (\"Data otrzymania zapłaty\").",
            "example": 2
          },
          "subDate": {
            "type": "string",
            "format": "date",
            "description": "Data sprzedaży / świadczenia usług. Dla faktur KSeF i Zamówienia domyślnie przyjmowana jest issueDate, jeśli nie podasz."
          },
          "subDateHeaderId": {
            "type": "number",
            "description": "ID nagłówka daty sprzedaży ze słownika additionalDateHeaders (np. 1 => \"Data wykonania usługi\").",
            "example": 1
          },
          "subDateTo": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Koniec okresu sprzedaży (KSeF OkresFa, P_6_Do). Z nim subDate jest początkiem okresu, np. usługa za cały miesiąc. Bez niego subDate to jedna data sprzedaży (P_6). Faktura korygująca bez subDate przejmuje datę albo okres sprzedaży korygowanej faktury."
          },
          "taxPointRule": {
            "type": "string",
            "nullable": true,
            "enum": [
              "art19a5p3a",
              "art19a5p3b",
              "art19a5p3c",
              "art19a5p4",
              null
            ],
            "description": "Obowiązek podatkowy z datą wystawienia faktury (art. 19a ust. 5 ustawy o VAT): art19a5p3a usługi budowlane (najpóźniej 30. dnia od wykonania), art19a5p3b dostawa książek i prasy (60. dnia), art19a5p3c druk książek i prasy (90. dnia), art19a5p4 media, telekomunikacja, najem, dzierżawa, leasing, ochrona, stała obsługa prawna i biurowa (najpóźniej z upływem terminu płatności). Nie trafia do KSeF; decyduje o okresie w raportach VAT i o dniu kursu waluty. null = zwykłe zasady (data sprzedaży)."
          },
          "exchangeRateDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Dzień tabeli NBP, z której jest exchangeRate. Według art. 31a ustawy o VAT to ostatni dzień roboczy przed dniem powstania obowiązku podatkowego (zwykle przed datą sprzedaży), a gdy faktura jest wcześniejsza, przed datą wystawienia. Korekta bez exchangeRate przejmuje kurs, jego dzień i tabelę z korygowanej faktury (art. 31b ust. 1)."
          },
          "exchangeRateTable": {
            "type": "string",
            "nullable": true,
            "maxLength": 32,
            "example": "190/A/NBP/2026",
            "description": "Numer tabeli NBP kursu exchangeRate, drukowany na PDF obok kursu."
          },
          "paymentInstallments": {
            "type": "array",
            "maxItems": 100,
            "description": "Raty o własnych kwotach (np. większa pierwsza rata): co najmniej dwa terminy płatności z kwotami (KSeF TerminPlatnosci, kwoty rat trafiają do DodatkowyOpis). Tylko przy paymentStatusId=1; suma rat musi być równa kwocie do zapłaty co do grosza, terminy po kolei i nie wcześniej niż data wystawienia. Bez paymentDeadlineDate terminem płatności dokumentu jest pierwsza rata. Równe raty: zamiast liczyć kwoty, podaj paymentInstallmentsSplit (nie łącz obu pól).",
            "items": {
              "type": "object",
              "required": [
                "date",
                "amount"
              ],
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-10-20"
                },
                "amount": {
                  "type": "number",
                  "example": 615
                }
              }
            }
          },
          "paymentInstallmentsSplit": {
            "type": "object",
            "nullable": true,
            "required": [
              "count"
            ],
            "description": "Równe raty wyliczone przez API: zalecane zawsze, gdy raty mają być równe. Podaj liczbę rat, a API po wyliczeniu sum dokumentu podzieli kwotę do zapłaty co do grosza: każda rata dostaje tyle samo, a grosze z zaokrąglenia trafiają do ostatniej (100,00 na 3 raty = 33,33 + 33,33 + 33,34). Dokument zapisuje zwykłe paymentInstallments (są w odpowiedzi i w podglądzie), a termin płatności (paymentDeadlineDate) to data pierwszej raty. Tylko przy paymentStatusId=1; przy tworzeniu bez paymentStatusId dokument dostaje status Do zapłaty. Raty o różnych kwotach (np. większa pierwsza rata) podaj w paymentInstallments; obu pól naraz nie łącz. PATCH bez products dzieli kwotę zapisaną w dokumencie. Błędy: 422 PAYMENT_INSTALLMENTS_INVALID. null = bez podziału.",
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 2,
                "maximum": 100,
                "example": 3,
                "description": "Liczba rat, od 2 do 100 (limit KSeF)."
              },
              "firstDate": {
                "type": "string",
                "format": "date",
                "example": "2026-10-21",
                "description": "Termin pierwszej raty, nie wcześniej niż data wystawienia. Domyślnie paymentDeadlineDate z żądania; przy aktualizacji zapisany termin płatności dokumentu do zapłaty; bez nich data wystawienia + 14 dni."
              },
              "every": {
                "type": "string",
                "enum": [
                  "month",
                  "week",
                  "14days"
                ],
                "default": "month",
                "example": "month",
                "description": "Odstęp między ratami: month co miesiąc (liczone od pierwszej daty: 31.01, 28.02, 31.03), week co 7 dni, 14days co 14 dni. Domyślnie month."
              }
            }
          },
          "paymentDeadlineTerm": {
            "type": "object",
            "nullable": true,
            "description": "Termin płatności opisany słowami (KSeF TerminOpis), np. 14 dni od dnia wystawienia faktury. Drukowany obok daty terminu.",
            "required": [
              "count",
              "unit",
              "event"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9999,
                "example": 14
              },
              "unit": {
                "type": "string",
                "enum": [
                  "day",
                  "week",
                  "month"
                ],
                "example": "day"
              },
              "event": {
                "type": "string",
                "enum": [
                  "issue",
                  "invoice_delivery",
                  "supply",
                  "acceptance"
                ],
                "example": "issue",
                "description": "Od czego liczy się termin: issue wystawienie faktury, invoice_delivery doręczenie faktury, supply dostawa towaru lub wykonanie usługi, acceptance odbiór."
              }
            }
          },
          "advanceReceipts": {
            "type": "array",
            "maxItems": 31,
            "description": "Faktura zaliczkowa dokumentująca kilka wpłat (KSeF ZaliczkaCzesciowa): co najmniej dwie wpłaty z datami otrzymania nie późniejszymi niż data wystawienia i sumą równą advancePaymentAmount, przy paymentStatusId=0. W walucie obcej każda wpłata ma swój kurs z dnia roboczego przed jej otrzymaniem (art. 31a). Każda wpłata to osobny obowiązek podatkowy w raportach VAT. Przy innych typach pole jest pomijane.",
            "items": {
              "type": "object",
              "required": [
                "date",
                "amount"
              ],
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-09-10"
                },
                "amount": {
                  "type": "number",
                  "example": 500
                },
                "exchangeRate": {
                  "type": "number",
                  "nullable": true,
                  "example": 4.4512
                },
                "exchangeRateDate": {
                  "type": "string",
                  "format": "date",
                  "nullable": true,
                  "example": "2026-09-09"
                }
              }
            }
          },
          "bankAccounts": {
            "type": "array",
            "description": "Konta bankowe do pokazania na dokumencie. Pierwsze konto trafia do bankAccountNumber, kolejne do additionalBankAccounts.",
            "items": {
              "type": "object",
              "required": [
                "accountNumber"
              ],
              "properties": {
                "bank": {
                  "type": "string",
                  "nullable": true
                },
                "accountNumber": {
                  "type": "string"
                },
                "swift": {
                  "type": "string"
                },
                "accountDescription": {
                  "type": "string"
                },
                "bankOwnAccountType": {
                  "type": "number",
                  "enum": [
                    1,
                    2,
                    3
                  ],
                  "nullable": true
                }
              }
            }
          },
          "vatAccountNumber": {
            "type": "string",
            "description": "Numer rachunku VAT (split payment / MPP)."
          },
          "vatAccountBank": {
            "type": "string",
            "description": "Nazwa banku rachunku VAT."
          },
          "vatAccountSwift": {
            "type": "string",
            "description": "SWIFT rachunku VAT."
          },
          "vatAccountDescription": {
            "type": "string",
            "description": "Opis rachunku VAT."
          },
          "paymentMethodId": {
            "type": "integer",
            "enum": [
              1,
              2,
              3,
              4,
              5,
              6,
              7
            ],
            "description": "Id metody płatności: 1=Gotówka, 2=Karta, 3=Bon, 4=Czek, 5=Kredyt, 6=Przelew, 7=Płatność mobilna",
            "example": 6
          },
          "paymentStatusId": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "0=Zapłacono (wymaga additionalPaymentDate albo partialPayments), 1=Do zapłaty (wymaga paymentDeadlineDate)",
            "example": 1
          },
          "partialPayments": {
            "type": "array",
            "maxItems": 100,
            "description": "Zapłaty częściowe dokonane do dnia wystawienia (KSeF ZaplataCzesciowa). Przy paymentStatusId=1 ich suma musi być mniejsza niż kwota do zapłaty. Przy paymentStatusId=0 co najmniej dwie wpłaty o sumie równej kwocie do zapłaty. Data wpłaty nie może być późniejsza niż data wystawienia.",
            "items": {
              "type": "object",
              "required": [
                "amount",
                "date"
              ],
              "properties": {
                "amount": {
                  "type": "number",
                  "example": 500
                },
                "date": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-09-14"
                },
                "paymentMethodId": {
                  "type": "integer",
                  "enum": [
                    1,
                    2,
                    3,
                    4,
                    5,
                    6,
                    7
                  ],
                  "nullable": true,
                  "description": "Forma wpłaty jak paymentMethodId; brak = nie podano",
                  "example": 1
                }
              }
            }
          },
          "annotations": {
            "$ref": "#/components/schemas/AnnotationsInput"
          },
          "additionalInfo": {
            "$ref": "#/components/schemas/AdditionalInfoInput"
          },
          "linkedOrderId": {
            "type": "string",
            "description": "ID zamówienia (wymagane dla FakturaZaliczka)"
          },
          "advancePaymentAmount": {
            "type": "number",
            "minimum": 0.01,
            "description": "Kwota zaliczki (wymagane dla FakturaZaliczka)"
          },
          "correctedInvoiceId": {
            "type": "string",
            "description": "ID faktury korygowanej (wymagane dla FakturaKorygujaca, FakturaKorygujacaZaliczkowa i FakturaKorygujacaRozliczeniowa). Gdy nie podasz nabywcy, odbiorcy, waluty albo adnotacji, korekta przejmuje je z tej faktury."
          },
          "correctionReason": {
            "type": "string",
            "maxLength": 256,
            "description": "Przyczyna korekty: opis, który trafia na PDF i do KSeF (PrzyczynaKorekty). Opcjonalna, najwyżej 256 znaków (limit KSeF)."
          },
          "correctionCause": {
            "type": "string",
            "nullable": true,
            "enum": [
              "after_sale",
              "mistake",
              null
            ],
            "example": "after_sale",
            "description": "Powód korekty: after_sale (zdarzenie po sprzedaży: rabat, zwrot towaru, reklamacja, cena albo ilość zmieniona po sprzedaży) albo mistake (błąd na fakturze korygowanej). Ustala TypKorekty wysyłany do KSeF, gdy nie podasz correctionType, i okres, w którym korekta wchodzi do raportów VAT i KPiR. Bez powodu korekta trafia do KSeF z TypKorekty 2, jak dotąd. Dotyczy tylko faktur korygujących, przy innych typach pole jest pomijane."
          },
          "correctionType": {
            "type": "integer",
            "nullable": true,
            "enum": [
              1,
              2,
              3,
              null
            ],
            "example": 1,
            "description": "TypKorekty w KSeF ustawiony ręcznie: 1 = skutek w dacie ujęcia faktury pierwotnej, 2 = w dacie wystawienia faktury korygującej, 3 = w innej dacie. Pomiń, a Fakturnia wyliczy go przy wysyłce: after_sale albo brak powodu daje 2, mistake daje 1, gdy korekta podnosi kwoty, ich nie zmienia albo zeruje całą fakturę (zły nabywca, duplikat), 2, gdy je obniża, i 3, gdy jedną stawkę podnosi, a inną obniża. Dotyczy tylko faktur korygujących."
          },
          "correctionEffectDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Faktury korygujące: dzień, od którego korekta działa w VAT, gdy nie jest to ani data faktury korygowanej, ani data korekty. Przy zwiększeniu po sprzedaży (after_sale) to dzień powstania przyczyny, np. uzgodnienia podwyżki (art. 29a ust. 17); z innego miesiąca niż korekta daje TypKorekty 3. Przy ręcznym correctionType=3 to dzień skutku. KSeF nie ma na nią pola; raport VAT i JPK ujmują korektę w tym dniu."
          },
          "correctionConfirmationDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Faktury korygujące zmniejszające wystawione poza KSeF: dzień otrzymania potwierdzenia odbioru korekty przez nabywcę. Według art. 29a ust. 13a obniżka wchodzi do rozliczenia za okres, w którym przyszło potwierdzenie, i tak ujmuje ją raport VAT."
          },
          "linkedAdvanceInvoiceIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "ID faktur zaliczkowych do rozliczenia (wymagane dla FakturaRozliczeniowa)"
          },
          "prepaymentIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "settlementAmount": {
            "type": "number",
            "description": "Kwota rozliczenia (FakturaRozliczeniowa). Wartość przekazywana bez automatycznych wyliczeń."
          },
          "isSettlementAmountManual": {
            "type": "boolean",
            "description": "Czy settlementAmount podano ręcznie."
          },
          "signatures": {
            "type": "object",
            "description": "Podpisy na PDF (osoba uprawniona do wystawienia/odbioru).",
            "properties": {
              "issuerSignature": {
                "type": "object",
                "properties": {
                  "show": {
                    "type": "boolean"
                  },
                  "value": {
                    "type": "string"
                  }
                }
              },
              "receiverSignature": {
                "type": "object",
                "properties": {
                  "show": {
                    "type": "boolean"
                  },
                  "value": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "ksefJst": {
            "type": "boolean",
            "description": "Czy dokument jest dla JST (jednostki samorządu terytorialnego)"
          }
        }
      },
      "PatchDocumentRequestBody": {
        "type": "object",
        "description": "Aktualizacja częściowa (PATCH): zmieniają się tylko przesłane klucze; jawny null czyści pole.",
        "properties": {
          "correctionAdvanceAmountAfter": {
            "type": "number",
            "description": "Kwota zaliczki PO korekcie (FakturaKorygujacaZaliczkowa)."
          },
          "correctionSettlementAmountAfter": {
            "type": "number",
            "description": "Kwota rozliczenia PO korekcie (FakturaKorygujacaRozliczeniowa)."
          },
          "issueDate": {
            "type": "string",
            "format": "date",
            "description": "Data wystawienia (ISO 8601)",
            "example": "2026-05-07"
          },
          "documentNo": {
            "type": "integer",
            "minimum": 1,
            "description": "Opcjonalny numer dokumentu. Jeśli podany, zostanie użyty zamiast automatycznej numeracji.",
            "example": 1
          },
          "numberingFormat": {
            "type": "string",
            "enum": [
              "/MM/YYYY",
              "YYYY/MM/",
              "/YYYY/MM",
              "MM/YYYY/",
              "/YYYY",
              "YYYY/",
              "-MM-YYYY",
              "YYYY-MM-",
              "-YYYY-MM",
              "MM-YYYY-",
              "-YYYY",
              "YYYY-"
            ],
            "description": "Format numeracji (np. \"/MM/YYYY\"). Domyślnie z ustawień użytkownika.",
            "example": "/MM/YYYY"
          },
          "symbol": {
            "type": "string",
            "description": "Prefiks symbolu dokumentu (np. \"FV/\"). Domyślnie z ustawień.",
            "example": "FV/"
          },
          "documentNumber": {
            "type": "string",
            "description": "Pełny numer dokumentu do walidacji 1:1. Jeśli podany razem z documentNo, musi być spójny.",
            "example": "FV/1/05/2026"
          },
          "invoiceName": {
            "type": "string",
            "description": "Nazwa faktury (np. dla FV zaliczkowych)",
            "example": "Faktura zaliczkowa"
          },
          "buyerId": {
            "type": "string",
            "description": "ID istniejącego klienta w systemie. Nie stosować razem z buyer. Wymagane buyerId albo buyer (poza korektą, która przejmuje nabywcę z korygowanej faktury).",
            "example": "681a3b2c4d5e6f7a8b9c0d1e"
          },
          "buyer": {
            "$ref": "#/components/schemas/ClientReference"
          },
          "receiverId": {
            "type": "string",
            "description": "ID opcjonalnego odbiorcy (dla faktur z wieloma stronami)."
          },
          "receiver": {
            "$ref": "#/components/schemas/ClientReference"
          },
          "products": {
            "type": "array",
            "description": "Pozycje dokumentu. Korekty: pełna lista pozycji PO korekcie (sumy dokumentu to różnica względem korygowanej faktury). FakturaZaliczka: pomiń, pozycje to rozkład zaliczki na stawki VAT zamówienia.",
            "items": {
              "type": "object",
              "required": [
                "name",
                "unitOfMeasure",
                "quantity"
              ],
              "properties": {
                "name": {
                  "type": "string",
                  "example": "Usługa programistyczna"
                },
                "gtu": {
                  "type": "string",
                  "nullable": true,
                  "enum": [
                    "GTU_01",
                    "GTU_02",
                    "GTU_03",
                    "GTU_04",
                    "GTU_05",
                    "GTU_06",
                    "GTU_07",
                    "GTU_08",
                    "GTU_09",
                    "GTU_10",
                    "GTU_11",
                    "GTU_12",
                    "GTU_13",
                    null
                  ],
                  "description": "Kod GTU (opcjonalny)"
                },
                "pkwiu": {
                  "type": "string",
                  "nullable": true
                },
                "unitOfMeasure": {
                  "type": "string",
                  "example": "szt."
                },
                "quantity": {
                  "type": "number",
                  "example": 1
                },
                "netPrice": {
                  "type": "number",
                  "nullable": true,
                  "description": "Cena jednostkowa netto. Gdy podana, wartości netValue/amountOfVat/grossValue są wyliczane automatycznie.",
                  "example": 100
                },
                "grossPrice": {
                  "type": "number",
                  "nullable": true,
                  "description": "Cena jednostkowa brutto (alternatywa dla netPrice).",
                  "example": 123
                },
                "netValue": {
                  "type": "number",
                  "nullable": true,
                  "description": "Opcjonalne, wartości mogą zostać przeliczone automatycznie.",
                  "example": 100
                },
                "grossValue": {
                  "type": "number",
                  "nullable": true,
                  "description": "Opcjonalne, wartości mogą zostać przeliczone automatycznie.",
                  "example": 123
                },
                "amountOfVat": {
                  "type": "number",
                  "nullable": true,
                  "description": "Opcjonalne, wartości mogą zostać przeliczone automatycznie.",
                  "example": 23
                },
                "vatRate": {
                  "oneOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "string"
                    }
                  ],
                  "example": 23,
                  "description": "Stawka VAT zgodna ze słownikiem AppData.VatRates. Wartość jest walidowana, a taxSymbol generowany automatycznie. Brak = domyślna stawka konta (settings.defaultTaxRate). \"marza\" = pozycja w procedurze marży (art. 119 i 120 ustawy o VAT): podaj grossPrice, faktura pokazuje tylko kwoty brutto, w KSeF suma trafia do P_13_11; wymaga annotations.marginProcedure (inaczej 422 MARGIN_LINE_WITHOUT_PROCEDURE)."
                },
                "marginPurchaseValue": {
                  "type": "number",
                  "nullable": true,
                  "minimum": 0,
                  "description": "Tylko vatRate \"marza\": kwota nabycia całej pozycji brutto w PLN (towar używany: cena zakupu; biuro podróży: koszty usług nabytych dla turysty). Nie trafia na fakturę ani do KSeF; służy do marży i VAT od marży w rejestrze VAT i JPK. Brak = do uzupełnienia później. W korekcie pominięta: przejmowana z korygowanej pozycji o tej nazwie, proporcjonalnie do ilości.",
                  "example": 3000
                },
                "marginTaxRate": {
                  "type": "number",
                  "nullable": true,
                  "enum": [
                    23,
                    8,
                    5,
                    0,
                    null
                  ],
                  "description": "Tylko vatRate \"marza\": stawka VAT liczona od marży (VAT = marża × stawka / (100 + stawka); ujemna marża = VAT 0). Domyślnie 23.",
                  "example": 23
                },
                "discount": {
                  "type": "number",
                  "example": 0
                },
                "currency": {
                  "type": "string",
                  "example": "PLN"
                }
              }
            }
          },
          "useAccountDefaults": {
            "type": "boolean",
            "description": "Domyślnie true: brakujące pola dostają wartości z ustawień konta jak nowy dokument w aplikacji (uwagi, podpisy, miejsce wystawienia, automatyczne adnotacje MPP/marża z rachunkiem VAT, podstawa zwolnienia dla stawki zw, forma i status płatności, stawka VAT pozycji). Pole podane jawnie zawsze wygrywa. false = bez wartości domyślnych konta. Korekta i tak przejmuje nabywcę, odbiorcę, walutę i adnotacje z korygowanej faktury, jeśli ich nie podasz.",
            "example": true
          },
          "currency": {
            "type": "string",
            "description": "Waluta dokumentu (ISO 4217)",
            "example": "PLN"
          },
          "exchangeRate": {
            "type": "number",
            "description": "Kurs wymiany dla walut obcych"
          },
          "issuePlace": {
            "type": "string",
            "description": "Miejsce wystawienia",
            "example": "Warszawa"
          },
          "comments": {
            "type": "string",
            "description": "Uwagi do dokumentu"
          },
          "paymentDescription": {
            "type": "string",
            "description": "Opis płatności"
          },
          "showPaymentSection": {
            "type": "boolean",
            "description": "Czy pokazywać sekcję płatności na dokumencie/PDF. Dla Zamowienie można ustawić false."
          },
          "paymentDeadlineDate": {
            "type": "string",
            "format": "date",
            "description": "Termin płatności (wymagany gdy paymentStatusId=1). Przy statusie Zapłacono jest ignorowany."
          },
          "additionalPaymentDate": {
            "type": "string",
            "format": "date",
            "description": "Data otrzymania zapłaty (wymagana gdy paymentStatusId=0). Przy statusie Do zapłaty jest ignorowana."
          },
          "additionalPaymentDateHeaderId": {
            "type": "number",
            "description": "ID nagłówka daty płatności ze słownika paymentDateHeaders. Dla paymentStatusId=0 domyślnie ustawiane jest id=2 (\"Data otrzymania zapłaty\").",
            "example": 2
          },
          "subDate": {
            "type": "string",
            "format": "date",
            "description": "Data sprzedaży / świadczenia usług. Dla faktur KSeF i Zamówienia domyślnie przyjmowana jest issueDate, jeśli nie podasz."
          },
          "subDateHeaderId": {
            "type": "number",
            "description": "ID nagłówka daty sprzedaży ze słownika additionalDateHeaders (np. 1 => \"Data wykonania usługi\").",
            "example": 1
          },
          "subDateTo": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Koniec okresu sprzedaży (KSeF OkresFa, P_6_Do). Z nim subDate jest początkiem okresu, np. usługa za cały miesiąc. Bez niego subDate to jedna data sprzedaży (P_6). Faktura korygująca bez subDate przejmuje datę albo okres sprzedaży korygowanej faktury."
          },
          "taxPointRule": {
            "type": "string",
            "nullable": true,
            "enum": [
              "art19a5p3a",
              "art19a5p3b",
              "art19a5p3c",
              "art19a5p4",
              null
            ],
            "description": "Obowiązek podatkowy z datą wystawienia faktury (art. 19a ust. 5 ustawy o VAT): art19a5p3a usługi budowlane (najpóźniej 30. dnia od wykonania), art19a5p3b dostawa książek i prasy (60. dnia), art19a5p3c druk książek i prasy (90. dnia), art19a5p4 media, telekomunikacja, najem, dzierżawa, leasing, ochrona, stała obsługa prawna i biurowa (najpóźniej z upływem terminu płatności). Nie trafia do KSeF; decyduje o okresie w raportach VAT i o dniu kursu waluty. null = zwykłe zasady (data sprzedaży)."
          },
          "exchangeRateDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Dzień tabeli NBP, z której jest exchangeRate. Według art. 31a ustawy o VAT to ostatni dzień roboczy przed dniem powstania obowiązku podatkowego (zwykle przed datą sprzedaży), a gdy faktura jest wcześniejsza, przed datą wystawienia. Korekta bez exchangeRate przejmuje kurs, jego dzień i tabelę z korygowanej faktury (art. 31b ust. 1)."
          },
          "exchangeRateTable": {
            "type": "string",
            "nullable": true,
            "maxLength": 32,
            "example": "190/A/NBP/2026",
            "description": "Numer tabeli NBP kursu exchangeRate, drukowany na PDF obok kursu."
          },
          "paymentInstallments": {
            "type": "array",
            "maxItems": 100,
            "description": "Raty o własnych kwotach (np. większa pierwsza rata): co najmniej dwa terminy płatności z kwotami (KSeF TerminPlatnosci, kwoty rat trafiają do DodatkowyOpis). Tylko przy paymentStatusId=1; suma rat musi być równa kwocie do zapłaty co do grosza, terminy po kolei i nie wcześniej niż data wystawienia. Bez paymentDeadlineDate terminem płatności dokumentu jest pierwsza rata. Równe raty: zamiast liczyć kwoty, podaj paymentInstallmentsSplit (nie łącz obu pól).",
            "items": {
              "type": "object",
              "required": [
                "date",
                "amount"
              ],
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-10-20"
                },
                "amount": {
                  "type": "number",
                  "example": 615
                }
              }
            }
          },
          "paymentInstallmentsSplit": {
            "type": "object",
            "nullable": true,
            "required": [
              "count"
            ],
            "description": "Równe raty wyliczone przez API: zalecane zawsze, gdy raty mają być równe. Podaj liczbę rat, a API po wyliczeniu sum dokumentu podzieli kwotę do zapłaty co do grosza: każda rata dostaje tyle samo, a grosze z zaokrąglenia trafiają do ostatniej (100,00 na 3 raty = 33,33 + 33,33 + 33,34). Dokument zapisuje zwykłe paymentInstallments (są w odpowiedzi i w podglądzie), a termin płatności (paymentDeadlineDate) to data pierwszej raty. Tylko przy paymentStatusId=1; przy tworzeniu bez paymentStatusId dokument dostaje status Do zapłaty. Raty o różnych kwotach (np. większa pierwsza rata) podaj w paymentInstallments; obu pól naraz nie łącz. PATCH bez products dzieli kwotę zapisaną w dokumencie. Błędy: 422 PAYMENT_INSTALLMENTS_INVALID. null = bez podziału.",
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 2,
                "maximum": 100,
                "example": 3,
                "description": "Liczba rat, od 2 do 100 (limit KSeF)."
              },
              "firstDate": {
                "type": "string",
                "format": "date",
                "example": "2026-10-21",
                "description": "Termin pierwszej raty, nie wcześniej niż data wystawienia. Domyślnie paymentDeadlineDate z żądania; przy aktualizacji zapisany termin płatności dokumentu do zapłaty; bez nich data wystawienia + 14 dni."
              },
              "every": {
                "type": "string",
                "enum": [
                  "month",
                  "week",
                  "14days"
                ],
                "default": "month",
                "example": "month",
                "description": "Odstęp między ratami: month co miesiąc (liczone od pierwszej daty: 31.01, 28.02, 31.03), week co 7 dni, 14days co 14 dni. Domyślnie month."
              }
            }
          },
          "paymentDeadlineTerm": {
            "type": "object",
            "nullable": true,
            "description": "Termin płatności opisany słowami (KSeF TerminOpis), np. 14 dni od dnia wystawienia faktury. Drukowany obok daty terminu.",
            "required": [
              "count",
              "unit",
              "event"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9999,
                "example": 14
              },
              "unit": {
                "type": "string",
                "enum": [
                  "day",
                  "week",
                  "month"
                ],
                "example": "day"
              },
              "event": {
                "type": "string",
                "enum": [
                  "issue",
                  "invoice_delivery",
                  "supply",
                  "acceptance"
                ],
                "example": "issue",
                "description": "Od czego liczy się termin: issue wystawienie faktury, invoice_delivery doręczenie faktury, supply dostawa towaru lub wykonanie usługi, acceptance odbiór."
              }
            }
          },
          "advanceReceipts": {
            "type": "array",
            "maxItems": 31,
            "description": "Faktura zaliczkowa dokumentująca kilka wpłat (KSeF ZaliczkaCzesciowa): co najmniej dwie wpłaty z datami otrzymania nie późniejszymi niż data wystawienia i sumą równą advancePaymentAmount, przy paymentStatusId=0. W walucie obcej każda wpłata ma swój kurs z dnia roboczego przed jej otrzymaniem (art. 31a). Każda wpłata to osobny obowiązek podatkowy w raportach VAT. Przy innych typach pole jest pomijane.",
            "items": {
              "type": "object",
              "required": [
                "date",
                "amount"
              ],
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-09-10"
                },
                "amount": {
                  "type": "number",
                  "example": 500
                },
                "exchangeRate": {
                  "type": "number",
                  "nullable": true,
                  "example": 4.4512
                },
                "exchangeRateDate": {
                  "type": "string",
                  "format": "date",
                  "nullable": true,
                  "example": "2026-09-09"
                }
              }
            }
          },
          "bankAccounts": {
            "type": "array",
            "description": "Konta bankowe do pokazania na dokumencie. Pierwsze konto trafia do bankAccountNumber, kolejne do additionalBankAccounts.",
            "items": {
              "type": "object",
              "required": [
                "accountNumber"
              ],
              "properties": {
                "bank": {
                  "type": "string",
                  "nullable": true
                },
                "accountNumber": {
                  "type": "string"
                },
                "swift": {
                  "type": "string"
                },
                "accountDescription": {
                  "type": "string"
                },
                "bankOwnAccountType": {
                  "type": "number",
                  "enum": [
                    1,
                    2,
                    3
                  ],
                  "nullable": true
                }
              }
            }
          },
          "vatAccountNumber": {
            "type": "string",
            "description": "Numer rachunku VAT (split payment / MPP)."
          },
          "vatAccountBank": {
            "type": "string",
            "description": "Nazwa banku rachunku VAT."
          },
          "vatAccountSwift": {
            "type": "string",
            "description": "SWIFT rachunku VAT."
          },
          "vatAccountDescription": {
            "type": "string",
            "description": "Opis rachunku VAT."
          },
          "paymentMethodId": {
            "type": "integer",
            "enum": [
              1,
              2,
              3,
              4,
              5,
              6,
              7
            ],
            "description": "Id metody płatności: 1=Gotówka, 2=Karta, 3=Bon, 4=Czek, 5=Kredyt, 6=Przelew, 7=Płatność mobilna",
            "example": 6
          },
          "paymentStatusId": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "0=Zapłacono (wymaga additionalPaymentDate albo partialPayments), 1=Do zapłaty (wymaga paymentDeadlineDate)",
            "example": 1
          },
          "partialPayments": {
            "type": "array",
            "maxItems": 100,
            "description": "Zapłaty częściowe dokonane do dnia wystawienia (KSeF ZaplataCzesciowa). Przy paymentStatusId=1 ich suma musi być mniejsza niż kwota do zapłaty. Przy paymentStatusId=0 co najmniej dwie wpłaty o sumie równej kwocie do zapłaty. Data wpłaty nie może być późniejsza niż data wystawienia.",
            "items": {
              "type": "object",
              "required": [
                "amount",
                "date"
              ],
              "properties": {
                "amount": {
                  "type": "number",
                  "example": 500
                },
                "date": {
                  "type": "string",
                  "format": "date",
                  "example": "2026-09-14"
                },
                "paymentMethodId": {
                  "type": "integer",
                  "enum": [
                    1,
                    2,
                    3,
                    4,
                    5,
                    6,
                    7
                  ],
                  "nullable": true,
                  "description": "Forma wpłaty jak paymentMethodId; brak = nie podano",
                  "example": 1
                }
              }
            }
          },
          "annotations": {
            "$ref": "#/components/schemas/AnnotationsInput"
          },
          "additionalInfo": {
            "$ref": "#/components/schemas/AdditionalInfoInput"
          },
          "linkedOrderId": {
            "type": "string",
            "description": "ID zamówienia (wymagane dla FakturaZaliczka)"
          },
          "advancePaymentAmount": {
            "type": "number",
            "minimum": 0.01,
            "description": "Kwota zaliczki (wymagane dla FakturaZaliczka)"
          },
          "correctedInvoiceId": {
            "type": "string",
            "description": "ID faktury korygowanej (wymagane dla FakturaKorygujaca, FakturaKorygujacaZaliczkowa i FakturaKorygujacaRozliczeniowa). Gdy nie podasz nabywcy, odbiorcy, waluty albo adnotacji, korekta przejmuje je z tej faktury."
          },
          "correctionReason": {
            "type": "string",
            "maxLength": 256,
            "description": "Przyczyna korekty: opis, który trafia na PDF i do KSeF (PrzyczynaKorekty). Opcjonalna, najwyżej 256 znaków (limit KSeF)."
          },
          "correctionCause": {
            "type": "string",
            "nullable": true,
            "enum": [
              "after_sale",
              "mistake",
              null
            ],
            "example": "after_sale",
            "description": "Powód korekty: after_sale (zdarzenie po sprzedaży: rabat, zwrot towaru, reklamacja, cena albo ilość zmieniona po sprzedaży) albo mistake (błąd na fakturze korygowanej). Ustala TypKorekty wysyłany do KSeF, gdy nie podasz correctionType, i okres, w którym korekta wchodzi do raportów VAT i KPiR. Bez powodu korekta trafia do KSeF z TypKorekty 2, jak dotąd. Dotyczy tylko faktur korygujących, przy innych typach pole jest pomijane."
          },
          "correctionType": {
            "type": "integer",
            "nullable": true,
            "enum": [
              1,
              2,
              3,
              null
            ],
            "example": 1,
            "description": "TypKorekty w KSeF ustawiony ręcznie: 1 = skutek w dacie ujęcia faktury pierwotnej, 2 = w dacie wystawienia faktury korygującej, 3 = w innej dacie. Pomiń, a Fakturnia wyliczy go przy wysyłce: after_sale albo brak powodu daje 2, mistake daje 1, gdy korekta podnosi kwoty, ich nie zmienia albo zeruje całą fakturę (zły nabywca, duplikat), 2, gdy je obniża, i 3, gdy jedną stawkę podnosi, a inną obniża. Dotyczy tylko faktur korygujących."
          },
          "correctionEffectDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Faktury korygujące: dzień, od którego korekta działa w VAT, gdy nie jest to ani data faktury korygowanej, ani data korekty. Przy zwiększeniu po sprzedaży (after_sale) to dzień powstania przyczyny, np. uzgodnienia podwyżki (art. 29a ust. 17); z innego miesiąca niż korekta daje TypKorekty 3. Przy ręcznym correctionType=3 to dzień skutku. KSeF nie ma na nią pola; raport VAT i JPK ujmują korektę w tym dniu."
          },
          "correctionConfirmationDate": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Faktury korygujące zmniejszające wystawione poza KSeF: dzień otrzymania potwierdzenia odbioru korekty przez nabywcę. Według art. 29a ust. 13a obniżka wchodzi do rozliczenia za okres, w którym przyszło potwierdzenie, i tak ujmuje ją raport VAT."
          },
          "linkedAdvanceInvoiceIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "ID faktur zaliczkowych do rozliczenia (wymagane dla FakturaRozliczeniowa)"
          },
          "prepaymentIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "settlementAmount": {
            "type": "number",
            "description": "Kwota rozliczenia (FakturaRozliczeniowa). Wartość przekazywana bez automatycznych wyliczeń."
          },
          "isSettlementAmountManual": {
            "type": "boolean",
            "description": "Czy settlementAmount podano ręcznie."
          },
          "signatures": {
            "type": "object",
            "description": "Podpisy na PDF (osoba uprawniona do wystawienia/odbioru).",
            "properties": {
              "issuerSignature": {
                "type": "object",
                "properties": {
                  "show": {
                    "type": "boolean"
                  },
                  "value": {
                    "type": "string"
                  }
                }
              },
              "receiverSignature": {
                "type": "object",
                "properties": {
                  "show": {
                    "type": "boolean"
                  },
                  "value": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "ksefJst": {
            "type": "boolean",
            "description": "Czy dokument jest dla JST (jednostki samorządu terytorialnego)"
          }
        }
      }
    },
    "headers": {
      "X-Request-ID": {
        "description": "Unikalny identyfikator tego żądania. Podaj go w zgłoszeniu do pomocy dotyczącym konkretnego wywołania.",
        "schema": {
          "type": "string",
          "format": "uuid",
          "example": "3f1c9a2e-7b7d-4c1a-9c1e-2b6f0d8e5a11"
        }
      },
      "X-RateLimit-Limit": {
        "description": "Liczba żądań dozwolonych w bieżącym oknie dla tego endpointu (albo w oknie globalnym).",
        "schema": {
          "type": "integer",
          "example": 100
        }
      },
      "X-RateLimit-Remaining": {
        "description": "Liczba żądań pozostałych w bieżącym oknie.",
        "schema": {
          "type": "integer",
          "example": 97
        }
      },
      "X-RateLimit-Reset": {
        "description": "Czas uniksowy (sekundy), gdy bieżące okno się zresetuje.",
        "schema": {
          "type": "integer",
          "example": 1790000000
        }
      },
      "Retry-After": {
        "description": "Liczba sekund do odczekania przed ponowieniem (przy 429).",
        "schema": {
          "type": "integer",
          "example": 12
        }
      },
      "Idempotent-Replayed": {
        "description": "Obecny (true), gdy odpowiedź została odtworzona z wcześniejszego żądania o tym samym Idempotency-Key.",
        "schema": {
          "type": "string",
          "enum": [
            "true"
          ]
        }
      }
    },
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "OAuth2": {
        "type": "oauth2",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://prod.api.fakturnia.pl/v1/oauth/token",
            "scopes": {
              "documents:browse": "Wyszukiwanie dokumentów",
              "documents:read": "Pobieranie dokumentu po ID",
              "documents:download": "Pobieranie PDF dokumentu",
              "documents:create": "Tworzenie dokumentów",
              "documents:delete": "Usuwanie dokumentów",
              "documents:update": "Edycja dokumentów",
              "documents:update-payment-status": "Zmiana statusu płatności dokumentu",
              "documents:update-external-reference": "Powiązanie dokumentu z zamówieniem zewnętrznym",
              "documents:send-to-ksef": "Wysyłka dokumentów do KSeF",
              "ksef:read": "Podgląd statusu połączenia KSeF",
              "ksef:configure": "Konfiguracja połączenia KSeF",
              "ksef:test": "Test połączenia KSeF",
              "webhooks:read": "Podgląd webhooków i historii dostaw",
              "webhooks:create": "Tworzenie webhooków",
              "webhooks:update": "Edycja webhooków, rotacja sekretu i wysyłka testowa",
              "webhooks:delete": "Usuwanie webhooków",
              "email-accounts:browse": "Lista podłączonych kont pocztowych",
              "email-accounts:read": "Szczegóły konta pocztowego",
              "settings:read": "Podgląd ustawień",
              "settings:update": "Edycja ustawień",
              "gus:company:read": "Pobieranie danych firmy po NIP z GUS",
              "clients:browse": "Wyszukiwanie klientów",
              "clients:read": "Pobieranie klienta po ID",
              "clients:create": "Tworzenie klientów",
              "clients:update": "Edycja klientów",
              "clients:delete": "Usuwanie klientów",
              "products:browse": "Wyszukiwanie produktów",
              "products:read": "Pobieranie produktu po ID",
              "products:create": "Tworzenie produktów",
              "products:update": "Edycja produktów",
              "products:delete": "Usuwanie produktów",
              "warehouse:browse": "Lista magazynów",
              "warehouse:create": "Tworzenie magazynów",
              "warehouse:update": "Edycja magazynów",
              "warehouse:delete": "Usuwanie magazynów",
              "warehouse:stock:read": "Raport stanów magazynowych",
              "warehouse:adjust": "Korekty stanów (inwentaryzacja)",
              "warehouse:wz:create": "Wystawianie WZ do faktur",
              "warehouse:documents:create": "Wystawianie dokumentów magazynowych (WZ, PZ, PW, RW, MM)",
              "employees:browse": "Lista kont pracowniczych",
              "employees:create": "Tworzenie kont pracowniczych",
              "employees:update": "Edycja kont pracowniczych i uprawnień",
              "employees:delete": "Usuwanie kont pracowniczych",
              "recurring:browse": "Lista reguł cyklicznych",
              "recurring:read": "Szczegóły reguły i historia generacji",
              "recurring:toggle": "Pauza i wznowienie reguły",
              "activity:read": "Historia aktywności konta (właściciel i pracownicy)"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/documents/": {
      "get": {
        "operationId": "browseDocuments",
        "summary": "Pobierz listę dokumentów",
        "description": "Stronicowana lista dokumentów, od najnowszego. Łącz `documentType`, zakres dat wystawienia, identyfikatory nabywcy i `onlyUnlinked`, żeby znaleźć to, czego potrzebuje integracja.\n\n**Wymagane uprawnienie (Scope)**: `documents:browse`\n\n**Limit zapytań**: 10 / 30 s",
        "parameters": [
          {
            "name": "searchQuery",
            "in": "query",
            "required": false,
            "description": "Filtruj dokumenty według numeru dokumentu",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "itemsPerPage",
            "in": "query",
            "required": false,
            "description": "Liczba dokumentów na stronę (maks. 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 10
            }
          },
          {
            "name": "currentPage",
            "in": "query",
            "required": false,
            "description": "Numer bieżącej strony (liczony od 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "buyerNip",
            "in": "query",
            "required": false,
            "description": "Filtruj dokumenty według NIP nabywcy",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "buyerVatUE",
            "in": "query",
            "required": false,
            "description": "Filtruj dokumenty według numeru VAT UE nabywcy",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "buyerIdentifier",
            "in": "query",
            "required": false,
            "description": "Filtruj dokumenty według innego identyfikatora podatkowego nabywcy",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "excludeIds",
            "in": "query",
            "required": false,
            "description": "Lista identyfikatorów dokumentów (oddzielona przecinkami) do wykluczenia z wyników",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Kolejność listy (od najnowszych): createdAt = data utworzenia (domyślnie), issueDate = data wystawienia.",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "issueDate"
              ],
              "default": "createdAt"
            }
          },
          {
            "name": "onlyUnlinked",
            "in": "query",
            "required": false,
            "description": "Jeśli ustawiono na true, zwracane są tylko dokumenty bez externalSource (niepowiązane z żadnym zamówieniem zewnętrznym)",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "documentType",
            "in": "query",
            "required": false,
            "description": "Filtrowanie po typie dokumentu. Przyjmuje pojedynczy typ lub listę rozdzieloną przecinkami (np. FakturaVAT,FakturaKorygujaca)",
            "schema": {
              "type": "string",
              "example": "FakturaVAT"
            }
          },
          {
            "name": "dateFrom",
            "in": "query",
            "required": false,
            "description": "Filtrowanie po dacie wystawienia — dolna granica włącznie (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-01-01"
            }
          },
          {
            "name": "dateTo",
            "in": "query",
            "required": false,
            "description": "Filtrowanie po dacie wystawienia — górna granica włącznie (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-01-31"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista dokumentów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentListResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "documents": [],
                    "currentPage": 1,
                    "totalPages": 5,
                    "totalCount": 50,
                    "itemsPerPage": 10,
                    "searchQuery": "FV/2023/001"
                  },
                  "executionTime": 50
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe parametry zapytania",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:browse"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      },
      "post": {
        "operationId": "createDocument",
        "summary": "Utwórz nowy dokument",
        "description": "Tworzy fakturę albo dokument powiązany. Numery są nadawane automatycznie, chyba że podasz je jawnie. Sprzedawca pochodzi z profilu firmy. Zapłaty częściowe (partialPayments), które nie pasują do dokumentu, są odrzucane z 422 PARTIAL_PAYMENTS_INVALID. Identyfikatory nabywcy i odbiorcy podanych danymi podlegają regułom kontrahentów: brakujący identifierType jest ustalany (numer VAT UE wpisany w nip trafia jako vatEu do vatUE) i zgłaszany w data.warnings; sprzeczne dane (np. identifierType nip z DE123456789, vatEu z numerem PL albo XI, NIP z błędną cyfrą kontrolną, idWew u nabywcy) są odrzucane z 422 PARTY_IDENTIFIER_INVALID i nazwą pola (buyer.nip, receiver.vatUE). Równe raty: wyślij paymentInstallmentsSplit { count, firstDate?, every? }, a API podzieli końcową kwotę do zapłaty co do grosza (reszta w ostatniej racie) i zapisze zwykłe paymentInstallments; raty, których nie da się utworzyć (albo jednocześnie paymentInstallments i paymentInstallmentsSplit), są odrzucane z 422 PAYMENT_INSTALLMENTS_INVALID. Dokument ma najwyżej jedną aktualną korektę: nowa korekta dokumentu, który już ją ma, dostaje 409 CORRECTED_INVOICE_HAS_CORRECTION z numerem ostatniej korekty w łańcuchu; kolejną zmianę wystawiasz jako korektę tej korekty (correctedInvoiceId = jej id), więc jej stan przed obejmuje wcześniejsze zmiany. W KSeF korekta korekty wskazuje fakturę pierwotną (DaneFaKorygowanej).\n\n**Wymagane uprawnienie (Scope)**: `documents:create`\n\n**Idempotency-Key**: obsługiwany (odpowiedź zapamiętana 24 h; ponowienie z tym samym kluczem zwraca ten sam wynik).\n\n**Limit zapytań**: 30 / 60 s\n\n**Emitowane Webhooki**:\n- `document.created` (na statusach: 201)",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Unikalny klucz idempotencyjności (UUID v4 zalecane). Zabezpiecza przed duplikowaniem operacji przy retry. Przechowywany 24h.",
            "schema": {
              "type": "string",
              "example": "550e8400-e29b-41d4-a716-446655440000"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDocumentRequestBody"
              },
              "example": {
                "documentType": "FakturaVAT",
                "issueDate": "2026-05-07",
                "buyer": {
                  "nip": "5261040828",
                  "name": "Acme Corp Sp. z o.o.",
                  "street": "Marszałkowska 1",
                  "postalCode": "00-001",
                  "city": "Warszawa",
                  "country": "Polska",
                  "countryCode": "PL"
                },
                "products": [
                  {
                    "name": "Usługa programistyczna",
                    "unitOfMeasure": "szt.",
                    "quantity": 1,
                    "netPrice": 100,
                    "netValue": 100,
                    "grossValue": 123,
                    "amountOfVat": 23,
                    "vatRate": 23
                  }
                ],
                "paymentMethodId": 6,
                "paymentStatusId": 1,
                "paymentDeadlineDate": "2026-05-14"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dokument utworzony pomyślnie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSuccessResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "document": {
                      "id": "681a3b2c4d5e6f7a8b9c0d1e",
                      "documentNumber": "FV/1/05/2026",
                      "documentNo": 1,
                      "symbol": "FV/",
                      "documentType": "FakturaVAT",
                      "issueDate": "2026-05-07",
                      "issuePlace": "Warszawa",
                      "subDate": null,
                      "additionalPaymentDate": null,
                      "paymentDeadlineDate": "2026-05-14",
                      "buyer": {
                        "id": "681a3b2c4d5e6f7a8b9c0d2e",
                        "type": "company",
                        "name": "Acme Corp Sp. z o.o.",
                        "nip": "5261040828",
                        "street": "Marszałkowska 1",
                        "postalCode": "00-001",
                        "city": "Warszawa",
                        "country": "Polska",
                        "countryCode": "PL"
                      },
                      "seller": {
                        "id": null,
                        "type": "company",
                        "name": "Nasza Firma Sp. z o.o.",
                        "nip": "1234567890",
                        "street": "ul. Główna 10",
                        "postalCode": "00-100",
                        "city": "Kraków",
                        "country": "Polska",
                        "countryCode": "PL"
                      },
                      "receiver": null,
                      "grossSum": 123,
                      "currency": "PLN",
                      "exchangeRate": null,
                      "prepaymentIds": null,
                      "correctedInvoiceId": null,
                      "products": [
                        {
                          "id": "681a3b2c4d5e6f7a8b9c0d3f",
                          "name": "Usługa programistyczna",
                          "gtu": null,
                          "unitOfMeasure": "szt.",
                          "discount": 0,
                          "quantity": 1,
                          "netPrice": 100,
                          "netValue": 100,
                          "grossValue": 123,
                          "amountOfVat": 23,
                          "vatRate": 23
                        }
                      ],
                      "payment": {
                        "method": 6,
                        "status": 1,
                        "bankAccountNumber": "1212 1212 1212 1212 1212 1212"
                      },
                      "comments": null,
                      "marginProcedureId": null,
                      "vatAccountNumber": null,
                      "isSent": false,
                      "isDownloaded": false,
                      "isPrinted": false,
                      "hasReceiver": false,
                      "hasComments": false,
                      "hasGTU": false,
                      "hasDiscount": false,
                      "hasPaymentDescription": false,
                      "signatures": null,
                      "createdAt": "2026-05-07T10:30:00.000Z",
                      "updatedAt": "2026-05-07T10:30:00.000Z"
                    }
                  },
                  "message": "DOCUMENT_CREATED",
                  "executionTime": 142
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe ciało żądania (brak wymaganych pól, nieprawidłowe typy, niejednoznaczny nabywca/odbiorca)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "VALIDATION_ERROR",
                  "executionTime": 5,
                  "errors": [
                    {
                      "field": "documentType",
                      "code": "REQUIRED",
                      "message": "documentType jest wymagany."
                    },
                    {
                      "field": "buyerId + buyer",
                      "code": "AMBIGUOUS_PARTY",
                      "message": "Podaj albo buyerId, albo buyer, ale nie oba."
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany (brak lub nieprawidłowy token JWT)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "UNAUTHORIZED",
                  "executionTime": 2,
                  "errors": null
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak dostępu (brak aktywnego planu PRO/MAX, przekroczony limit dokumentów albo brak scope). Powody: „Subskrypcja nieaktywna. Do wystawiania dokumentów potrzebujesz aktywnego planu PRO lub MAX.”, „Subskrypcja wygasła. Do wystawiania dokumentów potrzebujesz aktywnego planu PRO lub MAX.”, „Osiągnięto limit N dokumentów w miesiącu. Wykup wyższą subskrypcję, aby tworzyć więcej dokumentów.”",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "DOCUMENT_LIMIT_EXCEEDED",
                  "executionTime": 18,
                  "errors": [
                    "Subskrypcja nieaktywna. Do wystawiania dokumentów potrzebujesz aktywnego planu PRO lub MAX."
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono powiązanego zasobu (nabywca, korygowana faktura, powiązane zamówienie itp.)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "BUYER_NOT_FOUND",
                  "executionTime": 8,
                  "errors": [
                    {
                      "code": "NOT_FOUND",
                      "message": "Klient o podanym ID nie został znaleziony."
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Numer dokumentu już istnieje albo korygowany dokument ma już korektę (CORRECTED_INVOICE_HAS_CORRECTION: skoryguj jego ostatnią korektę)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "NUMBER_ALREADY_EXISTS",
                  "executionTime": 15,
                  "errors": [
                    {
                      "code": "CONFLICT",
                      "message": "Dokument o numerze \"FV/5/05/2026\" już istnieje."
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Walidacja biznesowa nie powiodła się (sprzeczne adnotacje, brak dat płatności, wymagania zależne od typu, PARTIAL_PAYMENTS_INVALID gdy zapłaty częściowe nie pasują do dokumentu, PARTY_IDENTIFIER_INVALID gdy identyfikatory nabywcy albo odbiorcy są sprzeczne)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "ANNOTATIONS_VALIDATION_ERROR",
                  "executionTime": 11,
                  "errors": [
                    {
                      "code": "ANNOTATION_CONFLICT",
                      "message": "isSplitPayment (MPP) wyklucza się z isCashMethod (metoda kasowa)."
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "INTERNAL_SERVER_ERROR",
                  "executionTime": 5,
                  "errors": [
                    {
                      "code": "INTERNAL",
                      "message": "Unexpected error"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      }
    },
    "/documents/{id}": {
      "get": {
        "operationId": "getDocument",
        "summary": "Pobierz szczegóły dokumentu",
        "description": "Jeden dokument po id, z wyliczonymi sumami, polami płatności i stanem KSeF.\n\n**Wymagane uprawnienie (Scope)**: `documents:read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID dokumentu",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Szczegóły dokumentu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSuccessResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "document": {}
                  },
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe ID dokumentu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      },
      "delete": {
        "operationId": "deleteDocument",
        "summary": "Usuń dokument",
        "description": "Usuwa dokument, który nie jest w KSeF. Dokumentu potwierdzonego w KSeF (KSEF_CONFIRMED) albo oczekującego na potwierdzenie (KSEF_SENT) nie da się usunąć; wystaw korektę. Dokumenty powiązane są chronione jak w aplikacji: faktura z korektą (409 DOCUMENT_CORRECTED), faktura zaliczkowa rozliczona fakturą rozliczeniową (409 ADVANCE_INVOICE_SETTLED) i zamówienie z zaliczkami (400 ORDER_HAS_ADVANCE_INVOICES). Usunięcie dokumentu magazynowego (WZ, PZ, PW, RW, MM) cofa jego ruchy magazynowe; usunięcie ostatniej korekty odblokowuje fakturę korygowaną.\n\n**Wymagane uprawnienie (Scope)**: `documents:delete`\n\n**Emitowane Webhooki**:\n- `document.deleted` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID dokumentu do usunięcia",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dokument usunięty pomyślnie.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "681a3b2c4d5e6f7a8b9c0d1e"
                  },
                  "message": "Document deleted.",
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie, blokada KSeF (KSEF_CONFIRMED / KSEF_SENT), zamówienie z zaliczkami (ORDER_HAS_ADVANCE_INVOICES) albo brak parametrów.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany, brak lub nieprawidłowy token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak dostępu, brak uprawnienia documents:delete.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu lub dokument nie należy do uwierzytelnionego użytkownika.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:delete"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      },
      "put": {
        "operationId": "updateDocument",
        "summary": "Pełna aktualizacja istniejącego dokumentu",
        "description": "Zastępuje wszystkie edytowalne pola dokumentu. documentType jest niezmienny. Nabywcę wskażesz przez buyerId albo osadzony obiekt buyer. Sprzedawca pochodzi z profilu firmy. Zapłaty częściowe (partialPayments) obowiązują te same reguły co przy tworzeniu; błędne wpłaty odpowiadają 422 PARTIAL_PAYMENTS_INVALID. Nabywca albo odbiorca podany danymi podlega tym samym regułom identyfikatorów co przy tworzeniu (ustalony identifierType w data.warnings, 422 PARTY_IDENTIFIER_INVALID przy sprzeczności); identyfikatory równe zapisanym nie są ponownie sprawdzane. paymentInstallmentsSplit dzieli kwotę do zapłaty dokumentu po zmianie (bez products: kwotę zapisaną w dokumencie) na równe paymentInstallments, reszta w ostatniej racie; gdy raty nie dadzą się utworzyć, 422 PAYMENT_INSTALLMENTS_INVALID.\n\n**Wymagane uprawnienie (Scope)**: `documents:update`\n\n**Emitowane Webhooki**:\n- `document.updated` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID dokumentu do aktualizacji",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDocumentRequestBody"
              },
              "example": {
                "issueDate": "2026-09-26",
                "buyerId": "681a3b2c4d5e6f7a8b9c0d1e",
                "products": [
                  {
                    "name": "Usługa programistyczna",
                    "unitOfMeasure": "godz.",
                    "quantity": 10,
                    "netPrice": 150,
                    "vatRate": 23
                  }
                ],
                "paymentMethodId": 6,
                "paymentStatusId": 1,
                "paymentDeadlineDate": "2026-10-10",
                "comments": "Zamówienie #10234"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dokument zaktualizowany.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSuccessResponse"
                },
                "example": {
                  "success": true,
                  "message": "Document updated.",
                  "data": {
                    "document": {
                      "id": "64dddddddddddddddddddddd",
                      "documentType": "FakturaVAT",
                      "documentNumber": "FV/1/05/2026",
                      "issueDate": "2026-06-01",
                      "comments": "Updated comment"
                    }
                  },
                  "executionTime": 12
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe dane wejściowe, KSeF zablokowany lub brakujące parametry. Kody błędów: KSEF_CONFIRMED / KSEF_SENT (dokument jest już w KSeF), ORDER_HAS_ADVANCE_INVOICES (zamówienie zablokowane wystawionymi fakturami zaliczkowymi).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany, brak lub nieprawidłowy token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak dostępu: brak scope documents:update albo brak aktywnego planu PRO/MAX (DOCUMENT_LIMIT_EXCEEDED, powód „Subskrypcja nieaktywna. Do edycji i wysyłki dokumentów potrzebujesz aktywnego planu PRO lub MAX.” albo „Subskrypcja wygasła. ...”).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu lub dokument nie należy do uwierzytelnionego użytkownika.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "DOCUMENT_NUMBER_EXISTS: numer przesłany w documentNo jest zajęty w swojej serii (grupa typów dokumentu, format numeracji oraz miesiąc albo rok daty wystawienia) albo, gdy numer się zmienia, ten sam pełny numer ma już inny dokument na koncie.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji: nieprawidłowa treść, PARTIAL_PAYMENTS_INVALID (zapłaty częściowe nie pasują do dokumentu) albo PARTY_IDENTIFIER_INVALID (sprzeczne identyfikatory nabywcy albo odbiorcy).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      },
      "patch": {
        "operationId": "patchDocument",
        "summary": "Częściowa aktualizacja pola lub pól dokumentu",
        "description": "Aktualizuje tylko przesłane pola dokumentu. Wszystkie pola są opcjonalne, wyślij wyłącznie to, co ma się zmienić. documentType jest niezmienny. Sprzedawca pochodzi z profilu firmy. Zapłaty częściowe (partialPayments) obowiązują te same reguły co przy tworzeniu; błędne wpłaty odpowiadają 422 PARTIAL_PAYMENTS_INVALID. Nabywca albo odbiorca podany danymi podlega tym samym regułom identyfikatorów co przy tworzeniu (ustalony identifierType w data.warnings, 422 PARTY_IDENTIFIER_INVALID przy sprzeczności); identyfikatory równe zapisanym nie są ponownie sprawdzane. paymentInstallmentsSplit dzieli kwotę do zapłaty dokumentu po zmianie (bez products: kwotę zapisaną w dokumencie) na równe paymentInstallments, reszta w ostatniej racie; gdy raty nie dadzą się utworzyć, 422 PAYMENT_INSTALLMENTS_INVALID.\n\n**Wymagane uprawnienie (Scope)**: `documents:update`\n\n**Emitowane Webhooki**:\n- `document.updated` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID dokumentu do częściowej aktualizacji",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchDocumentRequestBody"
              },
              "example": {
                "paymentDeadlineDate": "2026-10-24",
                "comments": "Termin wydłużony na prośbę klienta"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dokument częściowo zaktualizowany.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentSuccessResponse"
                },
                "example": {
                  "success": true,
                  "message": "Document updated.",
                  "data": {
                    "document": {
                      "id": "64dddddddddddddddddddddd",
                      "documentType": "FakturaVAT",
                      "documentNumber": "FV/1/05/2026",
                      "comments": "Updated via PATCH",
                      "paymentDeadlineDate": "2026-06-15"
                    }
                  },
                  "executionTime": 8
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe dane wejściowe, puste ciało żądania lub KSeF zablokowany. Kody błędów: KSEF_CONFIRMED / KSEF_SENT (dokument jest już w KSeF), ORDER_HAS_ADVANCE_INVOICES (zamówienie zablokowane wystawionymi fakturami zaliczkowymi).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany, brak lub nieprawidłowy token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak dostępu: brak scope documents:update albo brak aktywnego planu PRO/MAX (DOCUMENT_LIMIT_EXCEEDED, powód „Subskrypcja nieaktywna. Do edycji i wysyłki dokumentów potrzebujesz aktywnego planu PRO lub MAX.” albo „Subskrypcja wygasła. ...”).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu lub dokument nie należy do uwierzytelnionego użytkownika.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "DOCUMENT_NUMBER_EXISTS: numer przesłany w documentNo jest zajęty w swojej serii (grupa typów dokumentu, format numeracji oraz miesiąc albo rok daty wystawienia) albo, gdy numer się zmienia, ten sam pełny numer ma już inny dokument na koncie.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji: nieprawidłowa treść, PARTIAL_PAYMENTS_INVALID (zapłaty częściowe nie pasują do dokumentu) albo PARTY_IDENTIFIER_INVALID (sprzeczne identyfikatory nabywcy albo odbiorcy).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      }
    },
    "/documents/{id}/download": {
      "get": {
        "operationId": "downloadDocument",
        "summary": "Pobierz dokument",
        "description": "Renderuje PDF dokumentu. Gdy kolejka renderowania jest pełna, API odpowiada 429 WAIT_PDF_QUEUE z Retry-After; ponów po tylu sekundach.\n\n**Wymagane uprawnienie (Scope)**: `documents:download`\n\n**Limit zapytań**: 5 / 60 s",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plik PDF (Content-Disposition: attachment)",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Kolejka renderowania PDF jest pełna (WAIT_PDF_QUEUE) — ponów po czasie z nagłówka Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:download"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      }
    },
    "/documents/validate": {
      "post": {
        "operationId": "validateDocument",
        "summary": "Walidacja próbna danych dokumentu (bez zapisu do bazy danych)",
        "description": "Uruchamia pełną walidację i zwraca podgląd (kolejny numer, ustalonego nabywcę/odbiorcę, sumy) bez zapisywania. Wymaga tego samego uprawnienia co tworzenie dokumentu. Podgląd pokazuje raty, które zostaną zapisane (paymentInstallments), także wyliczone z paymentInstallmentsSplit. Identyfikatory nabywcy i odbiorcy podanych danymi podlegają regułom kontrahentów: brakujący identifierType jest ustalany (numer VAT UE wpisany w nip trafia jako vatEu do vatUE) i zgłaszany w data.warnings; sprzeczne dane (np. identifierType nip z DE123456789, vatEu z numerem PL albo XI, NIP z błędną cyfrą kontrolną, idWew u nabywcy) są odrzucane z 422 PARTY_IDENTIFIER_INVALID i nazwą pola (buyer.nip, receiver.vatUE).\n\n**Wymagane uprawnienie (Scope)**: `documents:create`\n\n**Limit zapytań**: 30 / 60 s",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Unikalny klucz idempotencyjności. Dla /validate osobny keyPrefix niż dla /create.",
            "schema": {
              "type": "string",
              "example": "660e8400-e29b-41d4-a716-446655440001"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDocumentRequestBody"
              },
              "example": {
                "documentType": "FakturaVAT",
                "issueDate": "2026-05-07",
                "buyer": {
                  "nip": "5261040828",
                  "name": "Acme Corp Sp. z o.o.",
                  "street": "Marszałkowska 1",
                  "postalCode": "00-001",
                  "city": "Warszawa",
                  "country": "Polska",
                  "countryCode": "PL"
                },
                "products": [
                  {
                    "name": "Usługa programistyczna",
                    "unitOfMeasure": "szt.",
                    "quantity": 1,
                    "netPrice": 100,
                    "vatRate": 23
                  }
                ],
                "subDateHeaderId": 2,
                "paymentMethodId": 6,
                "paymentStatusId": 1,
                "paymentDeadlineDate": "2026-05-14"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Walidacja powiodła się, zwraca podgląd (bez zapisu do bazy danych)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidatePreviewResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "preview": {
                      "documentNo": 1,
                      "documentNumber": "FV/1/05/2026",
                      "symbol": "FV/",
                      "numberingFormat": "/MM/YYYY",
                      "seller": {
                        "type": "company",
                        "name": "Nasza Firma Sp. z o.o.",
                        "nip": "1234567890",
                        "street": "ul. Główna 10",
                        "postalCode": "00-100",
                        "city": "Kraków",
                        "country": "Polska",
                        "countryCode": "PL"
                      },
                      "buyer": {
                        "type": "company",
                        "name": "Acme Corp Sp. z o.o.",
                        "nip": "5261040828",
                        "street": "Marszałkowska 1",
                        "postalCode": "00-001",
                        "city": "Warszawa",
                        "country": "Polska",
                        "countryCode": "PL"
                      },
                      "receiver": null,
                      "hasReceiver": false,
                      "totals": {
                        "netSum": 100,
                        "vatSum": 23,
                        "grossSum": 123
                      },
                      "receivedPayment": "NOT_RECEIVED",
                      "warnings": []
                    },
                    "valid": true
                  },
                  "message": "VALIDATION_SUCCESSFUL",
                  "executionTime": 38
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe ciało żądania",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "VALIDATION_ERROR",
                  "executionTime": 4,
                  "errors": [
                    {
                      "field": "documentType",
                      "code": "REQUIRED",
                      "message": "documentType jest wymagany."
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "UNAUTHORIZED",
                  "executionTime": 2,
                  "errors": null
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak dostępu (brak wymaganego uprawnienia)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "NO_PERMISSIONS",
                  "executionTime": 3,
                  "errors": [
                    {
                      "code": "MISSING_SCOPE",
                      "message": "Wymagany scope: documents:create"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono powiązanego zasobu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "BUYER_NOT_FOUND",
                  "executionTime": 9,
                  "errors": [
                    {
                      "code": "NOT_FOUND",
                      "message": "Klient o podanym ID nie został znaleziony."
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Numer dokumentu już istnieje",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "NUMBER_ALREADY_EXISTS",
                  "executionTime": 12,
                  "errors": [
                    {
                      "code": "CONFLICT",
                      "message": "Dokument o numerze \"FV/5/05/2026\" już istnieje."
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Walidacja biznesowa nie powiodła się (także PARTY_IDENTIFIER_INVALID, gdy identyfikatory nabywcy albo odbiorcy są sprzeczne)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "PAYMENT_DEADLINE_REQUIRED",
                  "executionTime": 7,
                  "errors": [
                    {
                      "code": "MISSING_FIELD",
                      "message": "paymentStatusId=1 (Do zapłaty) wymaga paymentDeadlineDate."
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "INTERNAL_SERVER_ERROR",
                  "executionTime": 5,
                  "errors": [
                    {
                      "code": "INTERNAL",
                      "message": "Unexpected error"
                    }
                  ]
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      }
    },
    "/documents/{id}/payment-status": {
      "patch": {
        "operationId": "updateDocumentPaymentStatus",
        "summary": "Zaktualizuj status płatności dokumentu",
        "description": "Aktualizuje stan otrzymania zapłaty dla dokumentu. Obsługiwane wartości: RECEIVED lub NOT_RECEIVED. paymentDate (RRRR-MM-DD, opcjonalnie) to dzień, w którym wpłata wpłynęła; bez niego dzisiejszy dzień w Polsce, nie może być z przyszłości. Przy metodzie kasowej to dzień obowiązku podatkowego. Dozwolone tylko dla dokumentów ze statusem płatności \"Do zapłaty\" (payment.status=1) lub dokumentów zaimportowanych z KSeF (source=ksef).\n\n**Wymagane uprawnienie (Scope)**: `documents:update-payment-status`\n\n**Emitowane Webhooki**:\n- `document.paymentStatusChanged` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID dokumentu",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentStatusInput"
              },
              "example": {
                "receivedPayment": "RECEIVED"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status płatności zaktualizowany.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentPaymentStatusResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe dane wejściowe lub nieobsługiwany status płatności dokumentu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak dostępu (brak wymaganego uprawnienia)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:update-payment-status"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      }
    },
    "/documents/{id}/external-reference": {
      "patch": {
        "operationId": "updateDocumentExternalReference",
        "summary": "Powiąż dokument z zewnętrznym numerem zamówienia",
        "description": "Wiąże dokument z zamówieniem w systemie zewnętrznym (sklep, ERP), dzięki czemu można go odnaleźć przez `GET /documents?onlyUnlinked=false` i rozpoznać w webhookach.\n\n**Wymagane uprawnienie (Scope)**: `documents:update-external-reference`\n\n**Emitowane Webhooki**:\n- `document.updated` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID dokumentu",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExternalReferenceInput"
              },
              "example": {
                "externalSource": "woocommerce",
                "externalOrderId": "10234",
                "externalOrderNumber": "#10234"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Powiązanie zewnętrzne zaktualizowane",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentExternalReferenceResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak dostępu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:update-external-reference"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      },
      "delete": {
        "operationId": "deleteDocumentExternalReference",
        "summary": "Usuń powiązanie z zewnętrznym zamówieniem z dokumentu",
        "description": "Usuwa z dokumentu powiązanie z zamówieniem zewnętrznym.\n\n**Wymagane uprawnienie (Scope)**: `documents:update-external-reference`\n\n**Emitowane Webhooki**:\n- `document.updated` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID dokumentu",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Powiązanie zewnętrzne usunięte",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentExternalReferenceResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "681a3b2c4d5e6f7a8b9c0d1e",
                    "externalSource": null,
                    "externalOrderId": null,
                    "externalOrderNumber": null
                  },
                  "message": "External reference removed.",
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:update-external-reference"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      }
    },
    "/documents/{id}/margin-purchases": {
      "patch": {
        "operationId": "updateDocumentMarginPurchases",
        "summary": "Ustaw kwoty nabycia pozycji w procedurze marży",
        "description": "Ustawia kwotę nabycia (`marginPurchaseValue`, brutto, PLN) i stawkę VAT od marży (`marginTaxRate`) pozycji z `vatRate: \"marza\"`, wskazanych miejscem w `products`. To dane sprzedawcy do rejestru VAT i JPK, a nie treść faktury, więc można je zmienić także po wysłaniu dokumentu do KSeF albo po korekcie (biuro podróży poznaje koszty później; faktura pobrana z KSeF nigdy ich nie zawiera). Pominięty klucz zostawia zapisaną wartość, `null` ją czyści.\n\n**Wymagane uprawnienie (Scope)**: `documents:update`\n\n**Emitowane Webhooki**:\n- `document.updated` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID dokumentu",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarginPurchasesInput"
              },
              "example": {
                "lines": [
                  {
                    "index": 0,
                    "marginPurchaseValue": 1500,
                    "marginTaxRate": 23
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kwoty nabycia zapisane",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentMarginPurchasesResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak dostępu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "MARGIN_PURCHASES_INVALID albo MARGIN_LINE_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      }
    },
    "/documents/{id}/send-to-ksef": {
      "post": {
        "operationId": "sendDocumentToKsef",
        "summary": "Wyślij dokument do KSeF",
        "description": "Rozpoczyna natychmiastową wysyłkę istniejącego dokumentu do KSeF. API czeka na natychmiastowy wynik z KSeF (best effort). Jeśli KSeF nadal przetwarza dokument, endpoint zwraca odpowiedź sukcesu ze statusem przetwarzania, a klient powinien odpytywać endpoint statusu lub obsłużyć webhook document.sentToKSeF.\n\n**Wymagane uprawnienie (Scope)**: `documents:send-to-ksef`\n\n**Idempotency-Key**: obsługiwany (odpowiedź zapamiętana 24 h; ponowienie z tym samym kluczem zwraca ten sam wynik).\n\n**Limit zapytań**: 10 / 60 s\n\n**Emitowane Webhooki**:\n- `document.sentToKSeF` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID dokumentu do wysłania",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Opcjonalny klucz idempotencyjności umożliwiający bezpieczne ponawianie żądań wysyłki.",
            "schema": {
              "type": "string",
              "example": "550e8400-e29b-41d4-a716-446655440000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dokument wysłany i przetworzony w KSeF (dostępny ksefNumber).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KsefSendResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub dokument nie może zostać wysłany do KSeF.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak dostępu: brak scope documents:send-to-ksef albo brak aktywnego planu PRO/MAX (DOCUMENT_LIMIT_EXCEEDED, powód „Subskrypcja nieaktywna. Do edycji i wysyłki dokumentów potrzebujesz aktywnego planu PRO lub MAX.” albo „Subskrypcja wygasła. ...”).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Konflikt (już wysłany / już przetwarzany / brak połączenia z KSeF).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "KSEF_CONNECTION_NOT_AUTHORIZED: połączenie z KSeF istnieje, ale nie jest autoryzowane. KSEF_VALIDATION_FAILED: dokument nie spełnia wymagań KSeF sprawdzanych przed wysyłką (na przykład jest wysyłany w innym dniu niż data wystawienia albo NIP nabywcy ma błędną sumę kontrolną); `errors` wymienia przyczyny.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:send-to-ksef"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      }
    },
    "/documents/{id}/ksef-status": {
      "get": {
        "operationId": "getDocumentKsefStatus",
        "summary": "Pobierz status wysyłki dokumentu do KSeF",
        "description": "Zwraca uproszczony status KSeF na potrzeby odpytywania po wywołaniu send-to-ksef.\n\n**Wymagane uprawnienie (Scope)**: `documents:read`\n\n**Limit zapytań**: 5 / 60 s",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID dokumentu",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dane statusu KSeF",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KsefStatusResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono dokumentu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Zbyt wiele sprawdzeń statusu. Zwolnij odpytywanie (maks. 5 zapytań na minutę).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      }
    },
    "/documents/{id}/history": {
      "get": {
        "operationId": "getDocumentHistory",
        "summary": "Pobierz historię dokumentu",
        "description": "Dziennik jednego dokumentu, od najnowszego: CREATE, UPDATE (z różnicami pól w `changes`), SENT_BY_EMAIL, DOWNLOAD, KSEF_SENT, KSEF_ERROR, PAYMENT_RECEIVED, PAYMENT_REVERTED, DELETE i powiązania z fakturami zaliczkowymi lub rozliczeniowymi. Każdy wpis mówi, kto działał (właściciel lub pracownik) i, gdy to zapisano, skąd (`origin`: external_api, app, import). Stronicowany.\n\n**Wymagane uprawnienie (Scope)**: `documents:read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator dokumentu",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "currentPage",
            "in": "query",
            "required": false,
            "description": "Numer strony, od 1",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "itemsPerPage",
            "in": "query",
            "required": false,
            "description": "Rozmiar strony (domyślnie 20, maks. 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Strona dziennika, od najnowszego",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentHistoryResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "documentId": "681a3b2c4d5e6f7a8b9c0d1e",
                    "documentNumber": "FV/12/09/2026",
                    "entries": [
                      {
                        "id": "681a3b2c4d5e6f7a8b9c0d2a",
                        "type": "PAYMENT_RECEIVED",
                        "createdAt": "2026-09-26T12:00:00.000Z",
                        "actor": "employee",
                        "employeeId": "681a3b2c4d5e6f7a8b9c0d3b",
                        "employeeName": "Ewa Kowalska",
                        "origin": "external_api",
                        "changes": null,
                        "data": {
                          "origin": "external_api",
                          "receivedPayment": "RECEIVED"
                        }
                      },
                      {
                        "id": "681a3b2c4d5e6f7a8b9c0d29",
                        "type": "CREATE",
                        "createdAt": "2026-09-26T10:30:00.000Z",
                        "actor": "owner",
                        "employeeId": null,
                        "employeeName": null,
                        "origin": "external_api",
                        "changes": null,
                        "data": {
                          "origin": "external_api",
                          "source": "local"
                        }
                      }
                    ],
                    "currentPage": 1,
                    "itemsPerPage": 20,
                    "totalCount": 2,
                    "totalPages": 1
                  },
                  "executionTime": 9
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe parametry stronicowania (INVALID_PARAMS)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Dokument nie znaleziony (DOCUMENT_NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "documents:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "documents"
        ]
      }
    },
    "/clients/": {
      "get": {
        "operationId": "browseClients",
        "summary": "Pobierz listę klientów",
        "description": "Stronicowana lista kontrahentów. `searchQuery` dopasowuje nazwę, NIP, e-mail, imię i nazwisko (bez rozróżniania wielkości liter).\n\n**Wymagane uprawnienie (Scope)**: `clients:browse`\n\n**Limit zapytań**: 10 / 30 s",
        "parameters": [
          {
            "name": "searchQuery",
            "in": "query",
            "required": false,
            "description": "Filtruj klientów według nazwy, NIP lub adresu e-mail",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "itemsPerPage",
            "in": "query",
            "required": false,
            "description": "Liczba kontrahentów na stronę (maks. 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 10
            }
          },
          {
            "name": "currentPage",
            "in": "query",
            "required": false,
            "description": "Numer bieżącej strony (liczony od 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista klientów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientListResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "clients": [],
                    "currentPage": 1,
                    "totalPages": 5,
                    "totalCount": 50,
                    "itemsPerPage": 10,
                    "searchQuery": ""
                  },
                  "executionTime": 50
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe parametry zapytania",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "clients:browse"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "clients"
        ]
      },
      "post": {
        "operationId": "createClient",
        "summary": "Utwórz nowego klienta",
        "description": "Dodaje kontrahenta. Firma wymaga `name`, osoba `firstName` i `lastName`; identyfikator wskazany w `identifierType` jest wymagany. identifierType: nip (polski NIP, 10 cyfr z cyfrą kontrolną), vatEu (numer VAT UE z prefiksem kraju w vatUE, np. DE123456789; Grecja EL), other (kod kraju i otherTaxIdentifier, np. US i 12-3456789), idWew (jednostka wewnętrzna NIP-NNNNN), none (konsument). Bez identifierType API ustala typ (numer VAT UE wpisany w nip trafia jako vatEu do vatUE, kraj z jego prefiksu) i zgłasza to w data.warnings. Sprzeczne dane (nip z DE123456789, vatEu z numerem PL albo XI, NIP o złej długości albo z błędną cyfrą kontrolną, other bez kraju, nieznany identifierType) albo błędny e-mail odpowiadają 422 VALIDATION_ERROR z nazwą pola; NIP obecny już na koncie odpowiada 409.\n\n**Wymagane uprawnienie (Scope)**: `clients:create`\n\n**Emitowane Webhooki**:\n- `client.created` (na statusach: 200)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientInput"
              },
              "example": {
                "type": "company",
                "contractorType": "client",
                "identifierType": "nip",
                "name": "Acme Sp. z o.o.",
                "nip": "5261040828",
                "street": "Marszałkowska 1",
                "postalCode": "00-001",
                "city": "Warszawa",
                "country": "Polska",
                "countryCode": "PL",
                "email": "biuro@acme.pl"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Klient utworzony pomyślnie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "client": {}
                  },
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Klient z tym NIP już istnieje",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "clients:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "clients"
        ]
      }
    },
    "/clients/{id}": {
      "get": {
        "operationId": "getClient",
        "summary": "Pobierz szczegóły klienta",
        "description": "Jeden kontrahent po id.\n\n**Wymagane uprawnienie (Scope)**: `clients:read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID klienta",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Szczegóły klienta",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "client": {}
                  },
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe ID klienta",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono klienta",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "clients:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "clients"
        ]
      },
      "put": {
        "operationId": "updateClient",
        "summary": "Zaktualizuj istniejącego klienta",
        "description": "Pełne zastąpienie kontrahenta (PUT): pominięte pola opcjonalne są czyszczone. Te same reguły walidacji i identyfikatorów co przy tworzeniu (data.warnings zgłasza ustalony identifierType albo przeniesiony numer); identyfikatory i adresy e-mail są sprawdzane tylko wtedy, gdy różnią się od zapisanych.\n\n**Wymagane uprawnienie (Scope)**: `clients:update`\n\n**Emitowane Webhooki**:\n- `client.updated` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID klienta do aktualizacji",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientInput"
              },
              "example": {
                "type": "company",
                "contractorType": "client",
                "identifierType": "nip",
                "name": "Acme Sp. z o.o.",
                "nip": "5261040828",
                "street": "Marszałkowska 1",
                "postalCode": "00-001",
                "city": "Warszawa",
                "country": "Polska",
                "countryCode": "PL",
                "email": "biuro@acme.pl"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Klient zaktualizowany pomyślnie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "client": {}
                  },
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono klienta",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Konflikt NIP",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "clients:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "clients"
        ]
      },
      "delete": {
        "operationId": "deleteClient",
        "summary": "Usuń klienta",
        "description": "Usuwa kontrahenta z kartoteki. Wystawione dokumenty zachowują własną kopię danych nabywcy.\n\n**Wymagane uprawnienie (Scope)**: `clients:delete`\n\n**Emitowane Webhooki**:\n- `client.deleted` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID klienta do usunięcia",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Klient usunięty pomyślnie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "681a3b2c4d5e6f7a8b9c0d1e"
                  },
                  "message": "Client deleted.",
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono klienta",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "clients:delete"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "clients"
        ]
      }
    },
    "/products/": {
      "get": {
        "operationId": "browseProducts",
        "summary": "Pobierz listę produktów",
        "description": "Stronicowana lista produktów i usług. `searchQuery` dopasowuje nazwę.\n\n**Wymagane uprawnienie (Scope)**: `products:browse`\n\n**Limit zapytań**: 10 / 30 s",
        "parameters": [
          {
            "name": "searchQuery",
            "in": "query",
            "required": false,
            "description": "Filtruj produkty według nazwy",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "itemsPerPage",
            "in": "query",
            "required": false,
            "description": "Liczba produktów na stronę (maks. 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 10
            }
          },
          {
            "name": "currentPage",
            "in": "query",
            "required": false,
            "description": "Numer bieżącej strony (liczony od 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista produktów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductListResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "products": [],
                    "currentPage": 1,
                    "totalPages": 5,
                    "totalCount": 50,
                    "itemsPerPage": 10,
                    "searchQuery": ""
                  },
                  "executionTime": 50
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe parametry zapytania",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "products:browse"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "products"
        ]
      },
      "post": {
        "operationId": "createProduct",
        "summary": "Utwórz nowy produkt",
        "description": "Dodaje produkt lub usługę. Prześlij cenę jednostkową (`netPrice` albo `grossPrice`) i `vatRate`; wartość netto, kwota VAT i wartość brutto są liczone co do grosza.\n\n**Wymagane uprawnienie (Scope)**: `products:create`\n\n**Emitowane Webhooki**:\n- `product.created` (na statusach: 200)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductInput"
              },
              "example": {
                "name": "Usługa programistyczna",
                "unitOfMeasure": "szt.",
                "quantity": 1,
                "netPrice": 100,
                "vatRate": 23,
                "currency": "PLN"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Produkt utworzony",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "product": {}
                  },
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "products:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "products"
        ]
      }
    },
    "/products/{id}": {
      "get": {
        "operationId": "getProduct",
        "summary": "Pobierz szczegóły produktu",
        "description": "Jeden produkt po id.\n\n**Wymagane uprawnienie (Scope)**: `products:read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID produktu",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Szczegóły produktu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "product": {}
                  },
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono produktu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "products:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "products"
        ]
      },
      "put": {
        "operationId": "updateProduct",
        "summary": "Zaktualizuj istniejący produkt",
        "description": "Pełna aktualizacja produktu (PUT). Nowa `netPrice` (albo `vatRate`, `quantity`, `discount`) wysłana bez `netValue`, `amountOfVat` i `grossValue` przelicza je co do grosza, z rabatem. Wartości podane wprost są zapisywane bez zmian tylko wtedy, gdy się sumują (netto + VAT = brutto) i zgadzają ze stawką VAT i ceną; w przeciwnym razie 422 VALIDATION_ERROR wskazuje pole. Gdy pola ceny się nie zmieniają, zapisany produkt nie jest ponownie sprawdzany.\n\n**Wymagane uprawnienie (Scope)**: `products:update`\n\n**Emitowane Webhooki**:\n- `product.updated` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID produktu do aktualizacji",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductUpdateInput"
              },
              "example": {
                "name": "Usługa programistyczna (senior)",
                "unitOfMeasure": "godz.",
                "quantity": 1,
                "netPrice": 150,
                "vatRate": 23,
                "currency": "PLN"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Produkt zaktualizowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "product": {}
                  },
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono produktu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "products:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "products"
        ]
      },
      "delete": {
        "operationId": "deleteProduct",
        "summary": "Usuń produkt",
        "description": "Usuwa produkt z kartoteki. Wystawione dokumenty zachowują swoje pozycje.\n\n**Wymagane uprawnienie (Scope)**: `products:delete`\n\n**Emitowane Webhooki**:\n- `product.deleted` (na statusach: 200)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID produktu do usunięcia",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Produkt usunięty",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "681a3b2c4d5e6f7a8b9c0d1e"
                  },
                  "message": "Product deleted.",
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono produktu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "products:delete"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "products"
        ]
      }
    },
    "/dictionaries/": {
      "get": {
        "operationId": "getDictionaries",
        "summary": "Pobierz słowniki statyczne (typy dokumentów, metody płatności itp.)",
        "description": "Statyczne słowniki potrzebne do budowania dokumentów: typy dokumentów, metody i statusy płatności, stawki VAT, kody GTU, procedury marży, typy zwolnienia z VAT, waluty, kraje i nagłówki dat. Wystarczy ważny token, bez scope'a.",
        "responses": {
          "200": {
            "description": "Dane słownika",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DictionariesResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "data": null,
                  "message": "ERROR_CODE",
                  "executionTime": 42,
                  "errors": null
                }
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "dictionaries"
        ]
      }
    },
    "/ksef/connection": {
      "get": {
        "operationId": "getKsefConnection",
        "summary": "Pobierz status połączenia z KSeF",
        "description": "Stan połączenia konta z KSeF: czy skonfigurowano token KSeF albo certyfikat (`connectionType`, `hasToken`, `hasCertificate`) i czy jest autoryzowane, środowisko, uprawnienia i ostatni błąd. Sekrety nigdy nie są zwracane.\n\n**Wymagane uprawnienie (Scope)**: `ksef:read`",
        "responses": {
          "200": {
            "description": "Status połączenia z KSeF",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KsefConnectionResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "ksef:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "ksef"
        ]
      },
      "post": {
        "operationId": "upsertKsefConnection",
        "summary": "Utwórz lub zaktualizuj połączenie z KSeF (token albo certyfikat)",
        "description": "Zapisuje (lub zastępuje) połączenie konta z KSeF. Obsługiwane są dwie metody: token KSeF (`connectionType` TOKEN z `token`) albo certyfikat KSeF (`connectionType` CERTIFICATE z `certificateContent`, `privateKeyContent` i `privateKeyPassword`). Treść z polami certyfikatu i bez `connectionType` to połączenie certyfikatem. Zapis jednej metody zastępuje drugą. Sekrety są szyfrowane w spoczynku i nigdy nie są zwracane. Potem uruchom `POST /ksef/connection/test`, żeby autoryzować.\n\n**Wymagane uprawnienie (Scope)**: `ksef:configure`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KsefConnectionInput"
              },
              "examples": {
                "default": {
                  "summary": "Token KSeF",
                  "value": {
                    "connectionType": "TOKEN",
                    "token": "20260901-EC-1A2B3C4D5E-6F7A8B9C0D-E1|nip-5261040828|0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
                    "environment": "test"
                  }
                },
                "certificate": {
                  "summary": "Certyfikat KSeF",
                  "value": {
                    "certificateContent": "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----",
                    "privateKeyContent": "-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIF...\n-----END ENCRYPTED PRIVATE KEY-----",
                    "privateKeyPassword": "haslo-do-klucza",
                    "environment": "test"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Połączenie z KSeF zapisane",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KsefConnectionSavedResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono użytkownika",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "ksef:configure"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "ksef"
        ]
      },
      "delete": {
        "operationId": "deleteKsefConnection",
        "summary": "Dezaktywuj połączenie z KSeF",
        "description": "Dezaktywuje połączenie z KSeF i usuwa zapisane dane dostępowe (token KSeF albo certyfikat i klucz prywatny).\n\n**Wymagane uprawnienie (Scope)**: `ksef:configure`",
        "responses": {
          "200": {
            "description": "Połączenie z KSeF dezaktywowane",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KsefConnectionDeletedResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono połączenia",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "ksef:configure"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "ksef"
        ]
      }
    },
    "/ksef/connection/test": {
      "post": {
        "operationId": "testKsefConnection",
        "summary": "Przetestuj autoryzację i uprawnienia połączenia z KSeF",
        "description": "Uwierzytelnia się w KSeF zapisanymi danymi (tokenem KSeF albo certyfikatem) i zapisuje wynik na połączeniu. Odpowiada 200 z `isAuthorized` false, gdy KSeF odrzuci dane.\n\n**Wymagane uprawnienie (Scope)**: `ksef:test`\n\n**Limit zapytań**: 5 / 60 s",
        "responses": {
          "200": {
            "description": "Wynik testu połączenia z KSeF",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KsefConnectionTestResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono połączenia",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "ksef:test"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "ksef"
        ]
      }
    },
    "/webhooks/": {
      "get": {
        "operationId": "getWebhooks",
        "summary": "Lista webhooków",
        "description": "Wszystkie webhooki konta, od najnowszego, bez sekretów. Z parametrem `?endpoint=` odpowiedź mówi też, czy istnieje webhook dla tego adresu (używane przez wtyczki rejestrujące się przez POST /webhooks/initial).\n\n**Wymagane uprawnienie (Scope)**: `webhooks:read`",
        "parameters": [
          {
            "name": "endpoint",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Opcjonalny adres URL endpointu do sprawdzenia, czy istnieje początkowy webhook."
          }
        ],
        "responses": {
          "200": {
            "description": "Webhooki",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookListResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope albo brak planu MAX",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "webhooks:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "webhooks"
        ]
      },
      "post": {
        "operationId": "createWebhook",
        "summary": "Utwórz webhook",
        "description": "Rejestruje publiczny adres HTTPS dla wybranych zdarzeń. Sekret podpisujący jest zwracany raz, tylko w tej odpowiedzi; po jego utracie rotuj przez POST /webhooks/{id}/rotate-secret. Jeden webhook na adres.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:create`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookInput"
              },
              "example": {
                "endpoint": "https://erp.example.com/hooks/fakturnia",
                "events": [
                  "document.created",
                  "document.sentToKSeF",
                  "document.ksefRejected"
                ],
                "description": "ERP"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook utworzony; `secret` pokazany tylko tutaj",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookCreatedResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brak uwierzytelnienia (UNAUTHORIZED, TOKEN_EXPIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope (NO_PERMISSIONS) albo brak planu MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Webhook nie znaleziony (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Webhook dla tego adresu już istnieje (CONFLICT)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji: nieznane zdarzenie, pusta lista zdarzeń, prywatny albo nie-HTTP(S) adres (VALIDATION_ERROR)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "webhooks:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "webhooks"
        ]
      }
    },
    "/webhooks/initial": {
      "post": {
        "operationId": "createInitialWebhook",
        "summary": "Utwórz początkowy webhook wtyczki (wszystkie zdarzenia)",
        "description": "Endpoint dla wtyczek: rejestruje adres na wszystkie zdarzenia, idempotentnie per URL. Ponowne wywołanie dla tego samego adresu zwraca `created: false`; z `rotateSecret: true` wydaje nowy sekret. Własny zestaw zdarzeń ustawisz przez POST /webhooks.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:create`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InitialWebhookInput"
              },
              "example": {
                "endpoint": "https://shop.example.com/wp-json/fakturnia/v1/webhook",
                "siteName": "Sklep Example",
                "domain": "shop.example.com",
                "rotateSecret": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook utworzony albo już istniejący; `secret` obecny tylko przy utworzeniu albo rotacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InitialWebhookResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Brakujący, niebędący URL-em, prywatny albo nie-HTTP(S) adres (BAD_REQUEST)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope albo brak planu MAX",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "webhooks:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "webhooks"
        ]
      }
    },
    "/webhooks/{id}": {
      "get": {
        "operationId": "getWebhook",
        "summary": "Pobierz webhook",
        "description": "Zwraca jeden webhook z licznikami dostaw. Sekret podpisujący nigdy nie jest zwracany.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator webhooka (pole `id` obiektu webhooka)",
            "schema": {
              "type": "string",
              "example": "681a3b2c4d5e6f7a8b9c0d1e"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brak uwierzytelnienia (UNAUTHORIZED, TOKEN_EXPIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope (NO_PERMISSIONS) albo brak planu MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Webhook nie znaleziony (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "webhooks:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "webhooks"
        ]
      },
      "patch": {
        "operationId": "updateWebhook",
        "summary": "Zaktualizuj webhook",
        "description": "Aktualizacja częściowa: zmieniają się tylko klucze obecne w treści. `events` zastępuje całą listę subskrypcji. Ustawienie `status` na ACTIVE włącza ponownie webhook wyłączony automatycznie po serii niepowodzeń i zeruje licznik kolejnych błędów.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:update`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator webhooka (pole `id` obiektu webhooka)",
            "schema": {
              "type": "string",
              "example": "681a3b2c4d5e6f7a8b9c0d1e"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPatchInput"
              },
              "example": {
                "events": [
                  "document.created",
                  "document.paymentStatusChanged"
                ],
                "status": "ACTIVE"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Zaktualizowany webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brak uwierzytelnienia (UNAUTHORIZED, TOKEN_EXPIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope (NO_PERMISSIONS) albo brak planu MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Webhook nie znaleziony (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji: pusta treść, nieznane zdarzenie, status inny niż ACTIVE/INACTIVE, prywatny adres (VALIDATION_ERROR)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "webhooks:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "webhooks"
        ]
      },
      "delete": {
        "operationId": "deleteWebhook",
        "summary": "Usuń webhook",
        "description": "Usuwa webhook; oczekujące dostawy są anulowane i na jego adres nie trafiają już żadne zdarzenia.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:delete`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator webhooka (pole `id` obiektu webhooka)",
            "schema": {
              "type": "string",
              "example": "681a3b2c4d5e6f7a8b9c0d1e"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook usunięty",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brak uwierzytelnienia (UNAUTHORIZED, TOKEN_EXPIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope (NO_PERMISSIONS) albo brak planu MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Webhook nie znaleziony (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "webhooks:delete"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "webhooks"
        ]
      }
    },
    "/webhooks/{id}/rotate-secret": {
      "post": {
        "operationId": "rotateWebhookSecret",
        "summary": "Rotuj sekret podpisujący webhooka",
        "description": "Generuje nowy sekret i zwraca go jednorazowo. Dostawy wysłane po tym wywołaniu są podpisane nowym sekretem, więc najpierw zaktualizuj odbiorcę, potem rotuj.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:update`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator webhooka (pole `id` obiektu webhooka)",
            "schema": {
              "type": "string",
              "example": "681a3b2c4d5e6f7a8b9c0d1e"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Nowy sekret (pokazany tylko tutaj)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSecretResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brak uwierzytelnienia (UNAUTHORIZED, TOKEN_EXPIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope (NO_PERMISSIONS) albo brak planu MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Webhook nie znaleziony (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "webhooks:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "webhooks"
        ]
      }
    },
    "/webhooks/{id}/deliveries": {
      "get": {
        "operationId": "getWebhookDeliveries",
        "summary": "Lista ostatnich dostaw webhooka",
        "description": "Od najnowszej, stronicowane. Przydatne do diagnozowania odbiorcy: każdy wiersz pokazuje zdarzenie, liczbę prób, termin kolejnej próby i ostatni błąd. Rekordy dostaw są przechowywane 30 dni.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator webhooka (pole `id` obiektu webhooka)",
            "schema": {
              "type": "string",
              "example": "681a3b2c4d5e6f7a8b9c0d1e"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Tylko dostawy w tym stanie",
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "SUCCESS",
                "FAILED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "currentPage",
            "in": "query",
            "required": false,
            "description": "Numer strony, od 1",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "itemsPerPage",
            "in": "query",
            "required": false,
            "description": "Rozmiar strony (domyślnie 20, maks. 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dostawy, od najnowszej",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveriesResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieznany filtr statusu albo złe stronicowanie (INVALID_PARAMS)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brak uwierzytelnienia (UNAUTHORIZED, TOKEN_EXPIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope (NO_PERMISSIONS) albo brak planu MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Webhook nie znaleziony (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "webhooks:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "webhooks"
        ]
      }
    },
    "/webhooks/{id}/test": {
      "post": {
        "operationId": "testWebhook",
        "summary": "Wyślij dostawę testową do webhooka",
        "description": "Dostarcza zdarzenie `webhook.test` na endpoint od razu, podpisane jak prawdziwa dostawa, i raportuje wynik HTTP. Ping jest wysyłany niezależnie od subskrybowanych zdarzeń, nigdy nie jest ponawiany i nie liczy się do automatycznego wyłączenia.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:update`\n\n**Limit zapytań**: 5 / 60 s",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator webhooka (pole `id` obiektu webhooka)",
            "schema": {
              "type": "string",
              "example": "681a3b2c4d5e6f7a8b9c0d1e"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Wynik dostawy testowej (`ok` false, gdy endpoint nie odpowiedział 2xx)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTestResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brak uwierzytelnienia (UNAUTHORIZED, TOKEN_EXPIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope (NO_PERMISSIONS) albo brak planu MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Webhook nie znaleziony (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Za dużo dostaw testowych (maks. 5 na minutę)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "webhooks:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "webhooks"
        ]
      }
    },
    "/settings/": {
      "get": {
        "operationId": "getSettings",
        "summary": "Pobierz ustawienia ogólne i ustawienia numeracji",
        "description": "Ustawienia ogólne (format daty, newsletter) i numeracji (typ i format numeracji, symbole dokumentów) razem z dozwolonymi opcjami.\n\n**Wymagane uprawnienie (Scope)**: `settings:read`",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SettingsResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "settings:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "settings"
        ]
      }
    },
    "/settings/general": {
      "patch": {
        "operationId": "updateGeneralSettings",
        "summary": "Zaktualizuj ustawienia ogólne (format daty, newsletter)",
        "description": "Ustawia format dat drukowany na dokumentach i zgodę na newsletter.\n\n**Wymagane uprawnienie (Scope)**: `settings:update`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GeneralSettingsInput"
              },
              "example": {
                "dateFormat": "dd.MM.yyyy",
                "newsletter": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GeneralSettingsResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji (VALIDATION_ERROR): errors[] wskazuje każde błędne pole",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "settings:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "settings"
        ]
      }
    },
    "/settings/numbering": {
      "patch": {
        "operationId": "updateNumberingSettings",
        "summary": "Zaktualizuj ustawienia numeracji (typ, format, symbole)",
        "description": "Ustawia typ numeracji (miesięczna lub roczna), wzorzec daty w numerach dokumentów i prefiks symbolu per typ dokumentu.\n\n**Wymagane uprawnienie (Scope)**: `settings:update`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NumberingSettingsInput"
              },
              "example": {
                "numberingType": "MONTH",
                "numberingFormat": "/MM/YYYY",
                "documentSymbols": {
                  "FakturaVAT": "FV/",
                  "FakturaKorygujaca": "KOR/",
                  "Zamowienie": "ZAM/"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NumberingSettingsResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji (VALIDATION_ERROR): errors[] wskazuje każde błędne pole",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "settings:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "settings"
        ]
      }
    },
    "/company/nip-lookup": {
      "get": {
        "operationId": "lookupCompanyByNip",
        "summary": "Wyszukaj dane firmy w GUS po numerze NIP",
        "description": "Wyszukuje polską firmę w rejestrze GUS po NIP i zwraca jej nazwę i adres: `company` tak, jak figuruje w rejestrze, oraz `buyer` z nazwami pól kontrahenta, gotowy do przekazania jako `buyer` dokumentu albo body nowego kontrahenta.\n\n**Wymagane uprawnienie (Scope)**: `gus:company:read`\n\n**Limit zapytań**: 10 / 60 s",
        "parameters": [
          {
            "in": "query",
            "name": "nip",
            "required": true,
            "schema": {
              "type": "string",
              "example": "5261040828"
            },
            "description": "Polski numer NIP (10 cyfr)"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyLookupResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "NIP nie ma 10 cyfr albo ma błędną cyfrę kontrolną (INVALID_NIP)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "GUS nie ma firmy o tym NIP (COMPANY_NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "503": {
            "description": "Rejestr GUS nie odpowiedział (GUS_UNAVAILABLE); spróbuj ponownie za chwilę",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "gus:company:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "company"
        ]
      }
    },
    "/warehouse/": {
      "get": {
        "operationId": "browseWarehouses",
        "summary": "Pobierz listę magazynów",
        "description": "Wszystkie magazyny konta.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:browse`",
        "responses": {
          "200": {
            "description": "Lista magazynów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseListResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "warehouses": [
                      {
                        "id": "665f...",
                        "name": "Magazyn główny",
                        "symbol": "MAG1",
                        "address": "",
                        "isDefault": true
                      }
                    ]
                  },
                  "executionTime": 12
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Plan subskrypcji poniżej Pro (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:browse"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      },
      "post": {
        "operationId": "createWarehouse",
        "summary": "Utwórz magazyn (wymaga planu MAX)",
        "description": "Dodaje magazyn. Wymaga planu MAX.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:create`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WarehouseInput"
              },
              "example": {
                "name": "Magazyn główny",
                "symbol": "MAG1",
                "address": "ul. Prosta 1, 00-001 Warszawa",
                "isDefault": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Utworzono magazyn",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Plan poniżej MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      }
    },
    "/warehouse/stock": {
      "get": {
        "operationId": "getStockReport",
        "summary": "Pobierz raport stanów (suma ruchów per produkt/magazyn)",
        "description": "Stany magazynowe per produkt i magazyn, jako suma ruchów. `asOf` zwraca stan historyczny na koniec danego dnia, `warehouseId` zawęża do jednego magazynu, `productId` do jednego produktu.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:stock:read`",
        "parameters": [
          {
            "name": "asOf",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Stan historyczny na koniec danego dnia (YYYY-MM-DD)."
          },
          {
            "name": "warehouseId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Ogranicz raport do jednego magazynu."
          },
          {
            "name": "productId",
            "in": "query",
            "required": false,
            "description": "Tylko ten produkt",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Stany magazynowe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockReportResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "levels": [
                      {
                        "productId": "665f...",
                        "warehouseId": "665e...",
                        "quantity": 12
                      }
                    ],
                    "asOf": null
                  },
                  "executionTime": 18
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:stock:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      }
    },
    "/warehouse/movements": {
      "get": {
        "operationId": "getWarehouseMovements",
        "summary": "Lista ruchów magazynowych",
        "description": "Księga magazynowa, od najnowszego: każde przyjęcie i wydanie z dokumentem, ilością, kosztem jednostkowym i osobą, która je zapisała. Stany to suma tych wierszy. Filtry: produkt, magazyn, dokument, typ ruchu (PZ, WZ, PW, RW, MM_OUT, MM_IN, INW, WYCENA) i zakres dat. Stronicowana.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:stock:read`",
        "parameters": [
          {
            "name": "productId",
            "in": "query",
            "required": false,
            "description": "Tylko ruchy tego produktu",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "warehouseId",
            "in": "query",
            "required": false,
            "description": "Tylko ruchy w tym magazynie",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "documentId",
            "in": "query",
            "required": false,
            "description": "Tylko ruchy tego dokumentu magazynowego",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Typ ruchu albo lista rozdzielona przecinkami",
            "schema": {
              "type": "string",
              "example": "WZ,PZ"
            }
          },
          {
            "name": "dateFrom",
            "in": "query",
            "required": false,
            "description": "Data ruchu od, włącznie (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "dateTo",
            "in": "query",
            "required": false,
            "description": "Data ruchu do, włącznie (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "currentPage",
            "in": "query",
            "required": false,
            "description": "Numer strony, od 1",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "itemsPerPage",
            "in": "query",
            "required": false,
            "description": "Rozmiar strony (domyślnie 50, maks. 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Strona ruchów, od najnowszego",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockMovementsResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "movements": [
                      {
                        "id": "681a3b2c4d5e6f7a8b9c0d1e",
                        "productId": "681a3b2c4d5e6f7a8b9c0d2a",
                        "warehouseId": "681a3b2c4d5e6f7a8b9c0d3b",
                        "quantity": -2,
                        "unitCost": null,
                        "type": "WZ",
                        "documentId": "681a3b2c4d5e6f7a8b9c0d4c",
                        "documentNumber": "WZ/3/09/2026",
                        "date": "2026-09-26",
                        "note": null,
                        "employeeId": null,
                        "employeeName": null,
                        "createdAt": "2026-09-26T10:30:00.000Z"
                      }
                    ],
                    "currentPage": 1,
                    "itemsPerPage": 50,
                    "totalCount": 1,
                    "totalPages": 1
                  },
                  "executionTime": 11
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieznany typ ruchu, zła data albo stronicowanie (INVALID_PARAMS)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:stock:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      }
    },
    "/warehouse/adjustments": {
      "post": {
        "operationId": "createStockAdjustment",
        "summary": "Utwórz ręczną korektę stanu (ruch INW)",
        "description": "Zapisuje ręczną korektę stanu (inwentaryzacja, bilans otwarcia) jako ruch INW. Dodatnia ilość przyjmuje, ujemna wydaje. Ilość 0 z unitCost to przecena (ruch WYCENA): nowy średni koszt bieżącego stanu bez zmiany ilości; ilość 0 bez unitCost jest odrzucana (422).\n\n**Wymagane uprawnienie (Scope)**: `warehouse:adjust`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StockAdjustmentInput"
              },
              "example": {
                "productId": "681a3b2c4d5e6f7a8b9c0d1e",
                "warehouseId": "681a3b2c4d5e6f7a8b9c0d1f",
                "quantity": 25,
                "unitCost": 12.5,
                "date": "2026-09-26",
                "note": "Bilans otwarcia"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Zapisano korektę stanu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockAdjustmentResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono magazynu lub produktu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:adjust"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      }
    },
    "/warehouse/wz-from-invoice/{id}": {
      "post": {
        "operationId": "createWzFromInvoice",
        "summary": "Utwórz dokument WZ z faktury sprzedaży (tylko pozycje towarowe)",
        "description": "Wystawia dokument WZ (wydanie zewnętrzne) dla pozycji towarowych faktury sprzedaży. Pozycje usługowe i produkty bez kartoteki są pomijane. Jedno WZ na fakturę (409 przy duplikacie). WZ dostaje ustawienia konta dokumentu magazynowego (symbol i numeracja WZ, miejsce wystawienia, uwagi, podpisy, tryb potwierdzania wydań), odbiorcę z faktury i jest powiązane z fakturą w obie strony (numer WZ trafia na fakturę i do KSeF). Brak towaru odrzuca WZ (422 STOCK_SHORTAGE), chyba że allowNegativeStock=true; nieznany magazyn: 422 WAREHOUSE_INVALID.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:wz:create`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID faktury sprzedaży"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WzFromInvoiceInput"
              },
              "example": {
                "warehouseId": "681a3b2c4d5e6f7a8b9c0d1f"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Utworzono dokument WZ; skipped zawiera pominięte pozycje nietowarowe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WzFromInvoiceResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono faktury",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Do tej faktury istnieje już dokument WZ (CONFLICT)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Faktura bez pozycji towarowych albo to nie dokument sprzedaży (VALIDATION_ERROR), nieznany magazyn (WAREHOUSE_INVALID), brak towaru (STOCK_SHORTAGE)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:wz:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      }
    },
    "/warehouse/documents/validate": {
      "post": {
        "operationId": "validateWarehouseDocument",
        "summary": "Walidacja dokumentu magazynowego bez zapisu",
        "description": "Próbne wywołanie POST /warehouse/documents: pełna walidacja, numer, jaki dostałby dokument, magazyny, pozycje rozwiązane z kartoteki, stan przed i po dla każdej pozycji oraz braki, które zablokowałyby dokument wydania. Nic nie jest zapisywane (nowy kontrahent podany danymi nie powstaje). Wymaga planu MAX.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:documents:create`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WarehouseDocumentRequestBody"
              },
              "example": {
                "documentType": "PZ",
                "issueDate": "2026-09-26",
                "buyerId": "681a3b2c4d5e6f7a8b9c0d2e",
                "products": [
                  {
                    "productId": "681a3b2c4d5e6f7a8b9c0d1e",
                    "quantity": 20,
                    "netPrice": 45.5
                  }
                ],
                "comments": "Dostawa do magazynu głównego"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Walidacja poprawna: podgląd bez zapisu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseDocumentPreviewResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe ciało (typ, daty, pozycje)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono produktu, kontrahenta albo faktury źródłowej",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Nieznany magazyn albo MM bez magazynu docelowego (WAREHOUSE_INVALID), inne reguły biznesowe (VALIDATION_ERROR)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:documents:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      }
    },
    "/warehouse/documents": {
      "post": {
        "operationId": "createWarehouseDocument",
        "summary": "Wystawienie dokumentu magazynowego (WZ, PZ, PW, RW, MM)",
        "description": "Wystawia dokument magazynowy i księguje jego ruchy. Pozycje wskazują produkty z kartoteki (productId); nazwa, jednostka i cena pochodzą z kartoteki, jeśli ich nie podasz (PZ/PW: cena zakupu, WZ/RW/MM: cena sprzedaży). WZ/PZ przyjmują kontrahenta w buyerId/buyer (WZ: odbiorca, PZ: dostawca); PW/RW/MM go nie mają. Brak magazynu = magazyn domyślny (MM: źródłowy = domyślny, docelowy wymagany). Ustawienia konta działają jak w edytorze: symbol i numeracja, miejsce wystawienia, uwagi, podpisy z ustawienia podpisów magazynowych, status z ustawienia potwierdzania wydań (useAccountDefaults=false je wyłącza). Dokumenty wydania (WZ, RW, MM), które zeszłyby ze stanem poniżej zera, są odrzucane (422 STOCK_SHORTAGE), chyba że allowNegativeStock=true. WZ z sourceInvoiceId jest powiązane z fakturą w obie strony (numer trafia na fakturę). Wymaga planu MAX.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:documents:create`\n\n**Idempotency-Key**: obsługiwany (odpowiedź zapamiętana 24 h; ponowienie z tym samym kluczem zwraca ten sam wynik).\n\n**Limit zapytań**: 30 / 60 s\n\n**Emitowane Webhooki**:\n- `document.created` (na statusach: 201)",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Unikalny klucz idempotencyjności (UUID v4 zalecane). Zabezpiecza przed duplikowaniem operacji przy retry. Przechowywany 24h.",
            "schema": {
              "type": "string",
              "example": "550e8400-e29b-41d4-a716-446655440000"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WarehouseDocumentRequestBody"
              },
              "example": {
                "documentType": "PZ",
                "issueDate": "2026-09-26",
                "buyerId": "681a3b2c4d5e6f7a8b9c0d2e",
                "products": [
                  {
                    "productId": "681a3b2c4d5e6f7a8b9c0d1e",
                    "quantity": 20,
                    "netPrice": 45.5
                  }
                ],
                "comments": "Dostawa do magazynu głównego"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dokument magazynowy wystawiony, ruchy zaksięgowane",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseDocumentResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/Idempotent-Replayed"
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe ciało (typ, daty, pozycje)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono produktu, kontrahenta albo faktury źródłowej (PRODUCT_NOT_FOUND, CLIENT_NOT_FOUND, DOCUMENT_NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Numer dokumentu już istnieje (DOCUMENT_NUMBER_EXISTS)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Nieznany magazyn albo MM bez magazynu docelowego (WAREHOUSE_INVALID), stan zszedłby poniżej zera (STOCK_SHORTAGE), inne reguły biznesowe (VALIDATION_ERROR)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:documents:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      }
    },
    "/warehouse/{id}": {
      "put": {
        "operationId": "updateWarehouse",
        "summary": "Zaktualizuj magazyn",
        "description": "Pełne zastąpienie magazynu (PUT).\n\n**Wymagane uprawnienie (Scope)**: `warehouse:update`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID magazynu"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WarehouseInput"
              },
              "example": {
                "name": "Magazyn główny",
                "symbol": "MAG1",
                "address": "ul. Prosta 1, 00-001 Warszawa",
                "isDefault": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Zaktualizowano magazyn",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono magazynu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      },
      "delete": {
        "operationId": "deleteWarehouse",
        "summary": "Usuń magazyn (zablokowane, gdy ma ruchy magazynowe)",
        "description": "Usuwa magazyn. Odmowa (409), gdy ma jeszcze ruchy magazynowe albo jest jedynym magazynem konta.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:delete`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID magazynu"
          }
        ],
        "responses": {
          "200": {
            "description": "Usunięto magazyn",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono magazynu",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Magazyn ma ruchy magazynowe albo jest jedynym magazynem (CONFLICT)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:delete"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      },
      "get": {
        "operationId": "getWarehouse",
        "summary": "Pobierz magazyn",
        "description": "Jeden magazyn po id.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:browse`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator magazynu",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Magazyn",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Magazyn nie znaleziony (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "warehouse:browse"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "warehouse"
        ]
      }
    },
    "/employees/permissions": {
      "get": {
        "operationId": "getEmployeePermissions",
        "summary": "Pobierz rejestr dostępnych uprawnień pracowniczych",
        "description": "Rejestr uprawnień pracowniczych (klucz, grupa, etykieta, opis, uprawnienia implikowane). Wystarczy ważny token.",
        "responses": {
          "200": {
            "description": "Rejestr uprawnień (klucz + polska etykieta i opis)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmployeePermissionsResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "permissions": [
                      {
                        "key": "documents:read",
                        "label": "Podgląd dokumentów",
                        "description": "Przeglądanie faktur…"
                      }
                    ]
                  },
                  "executionTime": 4
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "employees"
        ]
      }
    },
    "/employees/": {
      "get": {
        "operationId": "browseEmployees",
        "summary": "Pobierz listę kont pracowniczych",
        "description": "Konta pracownicze właściciela, bez haseł. Wymaga planu MAX.\n\n**Wymagane uprawnienie (Scope)**: `employees:browse`",
        "responses": {
          "200": {
            "description": "Lista kont pracowniczych (nigdy nie zawiera haseł)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmployeeListResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "employees": [
                      {
                        "id": "665f...",
                        "firstName": "Jan",
                        "lastName": "Kowalski",
                        "emailAddress": "jan@firma.pl",
                        "permissions": [
                          "documents:read"
                        ],
                        "isActive": true
                      }
                    ]
                  },
                  "executionTime": 9
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Plan poniżej MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "employees:browse"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "employees"
        ]
      },
      "post": {
        "operationId": "createEmployee",
        "summary": "Utwórz konto pracownicze",
        "description": "Tworzy konto pracownicze (maks. 20 na koncie). E-mail musi być unikalny w całej Fakturni. Wymaga planu MAX.\n\n**Wymagane uprawnienie (Scope)**: `employees:create`",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmployeeInput"
              },
              "example": {
                "firstName": "Jan",
                "lastName": "Kowalski",
                "emailAddress": "jan@firma.pl",
                "password": "bardzo-tajne-haslo",
                "permissions": [
                  "documents:read",
                  "documents:write"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Utworzono konto pracownicze",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmployeeCreatedResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Plan poniżej MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Email zajęty (EMAIL_TAKEN) albo osiągnięto limit kont (EMPLOYEE_LIMIT_REACHED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "employees:create"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "employees"
        ]
      }
    },
    "/employees/{id}": {
      "put": {
        "operationId": "updateEmployee",
        "summary": "Zaktualizuj konto pracownicze (dane, uprawnienia, aktywacja, hasło)",
        "description": "Aktualizuje konto pracownicze: dane, hasło, pełną listę uprawnień albo `isActive` (false kończy sesje pracownika).\n\n**Wymagane uprawnienie (Scope)**: `employees:update`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID konta pracowniczego"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmployeeUpdateInput"
              },
              "example": {
                "permissions": [
                  "documents:read"
                ],
                "isActive": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Zaktualizowano konto pracownicze",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmployeeResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Plan poniżej MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono konta pracowniczego",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Email zajęty (EMAIL_TAKEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "employees:update"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "employees"
        ]
      },
      "delete": {
        "operationId": "deleteEmployee",
        "summary": "Usuń konto pracownicze (miękkie usunięcie, jego adres e-mail wraca do puli)",
        "description": "Usuwa konto pracownicze; jego e-mail wraca do puli.\n\n**Wymagane uprawnienie (Scope)**: `employees:delete`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "ID konta pracowniczego"
          }
        ],
        "responses": {
          "200": {
            "description": "Usunięto konto pracownicze",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Plan poniżej MAX (SUBSCRIPTION_REQUIRED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono konta pracowniczego",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "employees:delete"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "employees"
        ]
      },
      "get": {
        "operationId": "getEmployee",
        "summary": "Pobierz konto pracownicze",
        "description": "Jedno konto pracownicze po id, bez hasła.\n\n**Wymagane uprawnienie (Scope)**: `employees:browse`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator konta pracowniczego",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Konto pracownicze",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmployeeResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Pracownik nie znaleziony (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "employees:browse"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "employees"
        ]
      }
    },
    "/employees/{id}/activity": {
      "get": {
        "operationId": "getEmployeeActivity",
        "summary": "Pobierz aktywność pracownika",
        "description": "Co robił jeden pracownik, od najnowszego: logowania (z urządzeniem i IP), zmiany konta, akcje na dokumentach i operacje magazynowe. Paginacja kursorem: podaj `nextBefore` strony jako `before`, żeby pobrać kolejną; `scope` zawęża do jednego dziennika.\n\n**Wymagane uprawnienie (Scope)**: `employees:browse`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator konta pracowniczego",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "description": "Które dzienniki uwzględnić",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "auth",
                "management",
                "documents",
                "warehouse"
              ],
              "default": "all"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Kursor: tylko wpisy starsze niż ta data ISO (użyj `nextBefore` z poprzedniej strony)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Wpisów na stronę (domyślnie 30, maks. 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Strona aktywności pracownika",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmployeeActivityResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "employee": {
                      "id": "681a3b2c4d5e6f7a8b9c0d3b",
                      "firstName": "Ewa",
                      "lastName": "Kowalska",
                      "emailAddress": "ewa@firma.pl",
                      "permissions": [
                        "documents:read"
                      ],
                      "isActive": true,
                      "lastLoginAt": "2026-09-26T07:58:00.000Z",
                      "createdAt": "2026-09-01T10:00:00.000Z"
                    },
                    "items": [
                      {
                        "id": "681a3b2c4d5e6f7a8b9c0d1e",
                        "scope": "auth",
                        "type": "LOGIN",
                        "createdAt": "2026-09-26T07:58:00.000Z",
                        "employeeId": "681a3b2c4d5e6f7a8b9c0d3b",
                        "employeeName": "Ewa Kowalska",
                        "entityId": null,
                        "entityName": null,
                        "entityType": null,
                        "entityDeleted": false,
                        "changes": null,
                        "data": {
                          "ip": "203.0.113.5",
                          "device": "web"
                        }
                      }
                    ],
                    "hasMore": false,
                    "nextBefore": null
                  },
                  "executionTime": 12
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieznany zakres albo nieczytelna data (INVALID_PARAMS)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Pracownik nie znaleziony (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "employees:browse"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "employees"
        ]
      }
    },
    "/recurring-rules/": {
      "get": {
        "operationId": "browseRecurringRules",
        "summary": "Pobierz listę reguł dokumentów cyklicznych",
        "description": "Zwraca wszystkie reguły cykliczne wraz z podsumowaniem (liczby wg statusu, najbliższa zaplanowana generacja, miesięczny przychód brutto w PLN). Wymaga planu MAX.\n\n**Wymagane uprawnienie (Scope)**: `recurring:browse`",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filtruj według statusu reguły",
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "PAUSED",
                "FINISHED"
              ]
            }
          },
          {
            "name": "currentPage",
            "in": "query",
            "required": false,
            "description": "Numer strony, od 1",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "itemsPerPage",
            "in": "query",
            "required": false,
            "description": "Rozmiar strony (domyślnie 50, maks. 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista reguł cyklicznych z podsumowaniem",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringRuleListResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "rules": [
                      {
                        "id": "665f...",
                        "name": "Abonament — Firma Sp. z o.o.",
                        "status": "ACTIVE",
                        "mode": "AUTO",
                        "documentSummary": {
                          "documentType": "FakturaVAT",
                          "buyerName": "Firma Sp. z o.o.",
                          "grossSum": 1230,
                          "currency": "PLN"
                        },
                        "schedule": {
                          "frequency": "MONTHLY",
                          "dayOfMonth": 1,
                          "startDate": "2026-01-01",
                          "endType": "NEVER"
                        },
                        "nextRunAt": "2026-08-01",
                        "occurrencesCount": 7,
                        "documentsIssuedCount": 7
                      }
                    ],
                    "summary": {
                      "total": 3,
                      "active": 2,
                      "paused": 1,
                      "finished": 0,
                      "nextRunAt": "2026-08-01",
                      "monthlyRecurringGross": 2460
                    }
                  },
                  "executionTime": 11
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Plan subskrypcji niższy niż MAX (SUBSCRIPTION_REQUIRED) lub brak wymaganego uprawnienia",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "recurring:browse"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "recurring-rules"
        ]
      }
    },
    "/recurring-rules/{id}/history": {
      "get": {
        "operationId": "getRecurringRuleHistory",
        "summary": "Pobierz historię generacji reguły cyklicznej",
        "description": "Dziennik wystąpień reguły (od najnowszych) z odnośnikami do wygenerowanych dokumentów. Statusy: GENERATED, DRAFT, REMINDED, SKIPPED, FAILED, PENDING. Stronicowanie numerami stron (`currentPage`, `itemsPerPage`).\n\n**Wymagane uprawnienie (Scope)**: `recurring:read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID reguły cyklicznej",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "currentPage",
            "in": "query",
            "required": false,
            "description": "Numer strony, od 1",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "itemsPerPage",
            "in": "query",
            "required": false,
            "description": "Rozmiar strony (domyślnie 50, maks. 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Historia generacji reguły",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringRuleHistoryResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "runs": [
                      {
                        "id": "665f...",
                        "plannedDate": "2026-07-01",
                        "issueDate": "2026-07-01",
                        "documentId": "665a...",
                        "documentNumber": "FV/7/2026",
                        "status": "GENERATED",
                        "emailSent": true,
                        "ksefQueued": false
                      }
                    ],
                    "currentPage": 1,
                    "itemsPerPage": 50,
                    "totalCount": 1,
                    "totalPages": 1
                  },
                  "executionTime": 9
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Plan subskrypcji niższy niż MAX (SUBSCRIPTION_REQUIRED) lub brak wymaganego uprawnienia",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono reguły cyklicznej",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "recurring:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "recurring-rules"
        ]
      }
    },
    "/recurring-rules/{id}": {
      "get": {
        "operationId": "getRecurringRule",
        "summary": "Pobierz szczegóły reguły cyklicznej",
        "description": "Jedna reguła cykliczna z harmonogramem, automatyzacją i podsumowaniem generowanego dokumentu.\n\n**Wymagane uprawnienie (Scope)**: `recurring:read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID reguły cyklicznej",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Szczegóły reguły cyklicznej",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringRuleResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "rule": {}
                  },
                  "executionTime": 8
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Plan subskrypcji niższy niż MAX (SUBSCRIPTION_REQUIRED) lub brak wymaganego uprawnienia",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono reguły cyklicznej",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "recurring:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "recurring-rules"
        ]
      }
    },
    "/recurring-rules/{id}/toggle": {
      "patch": {
        "operationId": "toggleRecurringRule",
        "summary": "Wstrzymaj lub wznów regułę cykliczną",
        "description": "Treść: { \"active\": boolean }. Wstrzymanie czyści nextRunAt (null w czasie przerwy). Wznowienie liczy nextRunAt od dziś: pominięte wystąpienia NIE są nadrabiane, a wystąpienie wygenerowane już dziś nie jest powtarzane. Reguły FINISHED nie da się wznowić (409).\n\n**Wymagane uprawnienie (Scope)**: `recurring:toggle`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID reguły cyklicznej",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurringRuleToggleInput"
              },
              "example": {
                "active": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Zaktualizowana reguła",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringRuleResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "rule": {
                      "id": "665f...",
                      "status": "PAUSED"
                    }
                  },
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Plan subskrypcji niższy niż MAX (SUBSCRIPTION_REQUIRED) lub brak wymaganego uprawnienia",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Nie znaleziono reguły cyklicznej",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "409": {
            "description": "Reguła jest zakończona (FINISHED) i nie można jej wznowić",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "recurring:toggle"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "recurring-rules"
        ]
      }
    },
    "/email-accounts/": {
      "get": {
        "operationId": "browseEmailAccounts",
        "summary": "Lista kont pocztowych",
        "description": "Skrzynki podłączone w aplikacji (SMTP, Gmail, Outlook), z których wychodzą dokumenty wysyłane e-mailem, domyślna skrzynka pierwsza. Tylko odczyt: podłączanie, weryfikacja i edycja skrzynki odbywają się w aplikacji. Sekrety nigdy nie są zwracane.\n\n**Wymagane uprawnienie (Scope)**: `email-accounts:browse`",
        "responses": {
          "200": {
            "description": "Podłączone konta pocztowe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailAccountListResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope albo brak planu MAX",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "email-accounts:browse"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "email-accounts"
        ]
      }
    },
    "/email-accounts/{id}": {
      "get": {
        "operationId": "getEmailAccount",
        "summary": "Pobierz konto pocztowe",
        "description": "Jedna skrzynka po id, ze stanem weryfikacji. Sekrety nigdy nie są zwracane.\n\n**Wymagane uprawnienie (Scope)**: `email-accounts:read`",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identyfikator konta pocztowego",
            "schema": {
              "type": "string",
              "example": "681a3b2c4d5e6f7a8b9c0d1e"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Konto pocztowe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailAccountResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Brak scope albo brak planu MAX",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "404": {
            "description": "Konto pocztowe nie znalezione (NOT_FOUND)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Wewnętrzny błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "email-accounts:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "email-accounts"
        ]
      }
    },
    "/activity/": {
      "get": {
        "operationId": "getAccountActivity",
        "summary": "Pobierz aktywność konta",
        "description": "Wszystko, co działo się na koncie, od najnowszego: akcje na dokumentach (utworzenie, zmiana, wysyłka, zapłata, usunięcie), logowania i zarządzanie kontami pracowniczymi, operacje magazynowe. Łączy dzienniki właściciela i wszystkich pracowników. Paginacja kursorem: podaj `nextBefore` strony jako `before`, żeby pobrać kolejną. Filtry: `scope`, `employeeId` (id albo `main` dla samego właściciela), okno `from`/`to` i tekst `q` (imię i nazwisko pracownika albo numer dokumentu).\n\n**Wymagane uprawnienie (Scope)**: `activity:read`",
        "parameters": [
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "description": "Które dzienniki uwzględnić",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "auth",
                "management",
                "documents",
                "warehouse"
              ],
              "default": "all"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Kursor: tylko wpisy starsze niż ta data ISO (użyj `nextBefore` z poprzedniej strony)",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Wpisów na stronę (domyślnie 30, maks. 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          },
          {
            "name": "employeeId",
            "in": "query",
            "required": false,
            "description": "Tylko jeden pracownik (id) albo tylko konto właściciela (`main`)",
            "schema": {
              "type": "string",
              "example": "main"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Tylko wpisy od tej daty ISO włącznie",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Tylko wpisy do tej daty ISO włącznie",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Tekst: imię i nazwisko pracownika albo numer dokumentu",
            "schema": {
              "type": "string",
              "example": "FV/12"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Strona aktywności",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityFeedResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "items": [
                      {
                        "id": "681a3b2c4d5e6f7a8b9c0d1e",
                        "scope": "document",
                        "type": "CREATE",
                        "createdAt": "2026-09-26T10:30:00.000Z",
                        "employeeId": null,
                        "employeeName": null,
                        "entityId": "681a3b2c4d5e6f7a8b9c0d1f",
                        "entityName": "FV/12/09/2026",
                        "entityType": "DOCUMENT",
                        "entityDeleted": false,
                        "changes": null,
                        "data": {
                          "origin": "external_api",
                          "source": "local"
                        }
                      }
                    ],
                    "hasMore": true,
                    "nextBefore": "2026-09-26T10:30:00.000Z"
                  },
                  "executionTime": 14
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "Nieznany zakres albo nieczytelna data (INVALID_PARAMS)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Brakujący, nieprawidłowy albo wygasły token (UNAUTHORIZED, TOKEN_EXPIRED), albo unieważnione konto API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Nieoczekiwany błąd serwera (INTERNAL_SERVER_ERROR); bezpieczne ponowienie z tym samym Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": [
              "activity:read"
            ]
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "activity"
        ]
      }
    },
    "/auth/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Pobierz informacje o aktualnym koncie",
        "description": "Tożsamość i przyznane scope'y stojące za bieżącym tokenem. Użyj po wdrożeniu, żeby potwierdzić, że token działa i ma właściwe uprawnienia.",
        "responses": {
          "200": {
            "description": "Poprawnie pobrano dane konta",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthMeResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "clientId": "507f1f77bcf86cd799439011",
                    "name": "Integracja z e-Sklepem",
                    "scopes": [
                      "documents:read",
                      "clients:browse"
                    ],
                    "userId": "507f1f77bcf86cd799439012"
                  },
                  "executionTime": 10
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "401": {
            "description": "Nieautoryzowany",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "403": {
            "description": "Token bez wymaganego scope (NO_PERMISSIONS), właściciel bez planu MAX (SUBSCRIPTION_REQUIRED) albo adres IP spoza listy dozwolonych konta (FORBIDDEN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "429": {
            "description": "Przekroczony limit zapytań (RATE_LIMIT_EXCEEDED); odczekaj Retry-After sekund",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          }
        },
        "security": [
          {
            "OAuth2": []
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "auth"
        ]
      }
    }
  },
  "security": [
    {
      "BearerAuth": []
    },
    {
      "OAuth2": [
        "documents:browse",
        "documents:read",
        "documents:download",
        "documents:create",
        "documents:delete",
        "documents:update",
        "documents:update-payment-status",
        "documents:update-external-reference",
        "documents:send-to-ksef",
        "ksef:read",
        "ksef:configure",
        "ksef:test",
        "webhooks:read",
        "webhooks:create",
        "webhooks:update",
        "webhooks:delete",
        "email-accounts:browse",
        "email-accounts:read",
        "settings:read",
        "settings:update",
        "gus:company:read",
        "clients:browse",
        "clients:read",
        "clients:create",
        "clients:update",
        "clients:delete",
        "products:browse",
        "products:read",
        "products:create",
        "products:update",
        "products:delete",
        "warehouse:browse",
        "warehouse:create",
        "warehouse:update",
        "warehouse:delete",
        "warehouse:stock:read",
        "warehouse:adjust",
        "warehouse:wz:create",
        "warehouse:documents:create",
        "employees:browse",
        "employees:create",
        "employees:update",
        "employees:delete",
        "recurring:browse",
        "recurring:read",
        "recurring:toggle",
        "activity:read"
      ]
    }
  ],
  "tags": []
}
