{
  "info": {
    "name": "Fakturnia External REST API",
    "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        ",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{access_token}}",
        "type": "string"
      }
    ]
  },
  "event": [],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://prod.api.fakturnia.pl/external/v1",
      "type": "string"
    },
    {
      "key": "tokenUrl",
      "value": "https://prod.api.fakturnia.pl/v1/oauth/token",
      "type": "string"
    },
    {
      "key": "client_id",
      "value": "",
      "type": "string"
    },
    {
      "key": "client_secret",
      "value": "",
      "type": "string"
    },
    {
      "key": "access_token",
      "value": "",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "Authentication",
      "description": "Exchange client credentials for a bearer token. Run this first — the test script stores `access_token` for every other request.",
      "item": [
        {
          "name": "POST /v1/oauth/token — get access token",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{tokenUrl}}",
              "host": [
                "{{tokenUrl}}"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"grant_type\": \"client_credentials\",\n  \"client_id\": \"{{client_id}}\",\n  \"client_secret\": \"{{client_secret}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "OAuth 2.0 client-credentials flow. Returns a short-lived JWT used as the Bearer token on every other request."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.access_token) {",
                  "  pm.collectionVariables.set('access_token', json.access_token);",
                  "  pm.test('access_token captured', () => pm.expect(json.access_token).to.be.a('string'));",
                  "} else {",
                  "  pm.test('access_token captured', () => pm.expect.fail('no access_token in response'));",
                  "}"
                ]
              }
            }
          ],
          "response": []
        }
      ]
    },
    {
      "name": "auth",
      "item": [
        {
          "name": "GET /auth/me — Pobierz informacje o aktualnym koncie",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/auth/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "auth",
                "me"
              ]
            },
            "description": "Identity and granted scopes behind the current token. Use it after deployment to confirm the token works and carries the right scopes."
          },
          "response": []
        }
      ]
    },
    {
      "name": "documents",
      "item": [
        {
          "name": "GET /documents/ — Get list of documents",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/documents/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents"
              ],
              "query": [
                {
                  "key": "searchQuery",
                  "value": "",
                  "description": "Filter documents by document number",
                  "disabled": true
                },
                {
                  "key": "itemsPerPage",
                  "value": "",
                  "description": "Number of documents per page (max 100)",
                  "disabled": true
                },
                {
                  "key": "currentPage",
                  "value": "",
                  "description": "Current page number (starting from 1)",
                  "disabled": true
                },
                {
                  "key": "buyerNip",
                  "value": "",
                  "description": "Filter documents by buyer NIP",
                  "disabled": true
                },
                {
                  "key": "buyerVatUE",
                  "value": "",
                  "description": "Filter documents by buyer VAT UE number",
                  "disabled": true
                },
                {
                  "key": "buyerIdentifier",
                  "value": "",
                  "description": "Filter documents by buyer other tax identifier",
                  "disabled": true
                },
                {
                  "key": "excludeIds",
                  "value": "",
                  "description": "Comma-separated list of document IDs to exclude from results",
                  "disabled": true
                },
                {
                  "key": "sortBy",
                  "value": "",
                  "description": "Kolejność listy (od najnowszych): createdAt = data utworzenia (domyślnie), issueDate = data wystawienia.",
                  "disabled": true
                },
                {
                  "key": "onlyUnlinked",
                  "value": "",
                  "description": "If true, only return documents that have no externalSource (not linked to any external order)",
                  "disabled": true
                },
                {
                  "key": "documentType",
                  "value": "",
                  "description": "Filter by document type. Accepts a single type or a comma-separated list (e.g. FakturaVAT,FakturaKorygujaca)",
                  "disabled": true
                },
                {
                  "key": "dateFrom",
                  "value": "",
                  "description": "Filter by issue date — inclusive lower bound (YYYY-MM-DD)",
                  "disabled": true
                },
                {
                  "key": "dateTo",
                  "value": "",
                  "description": "Filter by issue date — inclusive upper bound (YYYY-MM-DD)",
                  "disabled": true
                }
              ]
            },
            "description": "Paginated list of documents, newest first. Combine `documentType`, the issue-date range, buyer identifiers and `onlyUnlinked` to find what an integration needs.\n\n**Wymagane uprawnienie (Scope)**: `documents:browse`\n\n**Limit zapytań**: 10 / 30 s\n\nRequired scope: `documents:browse`"
          },
          "response": []
        },
        {
          "name": "POST /documents/ — Create a new document",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/documents/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents"
              ]
            },
            "description": "Creates an invoice or related document. Numbers are auto-generated unless explicitly provided. Seller is taken from user.company. Partial payments (partialPayments) that do not fit the document are rejected with 422 PARTIAL_PAYMENTS_INVALID. Identifiers of a buyer or receiver given as data follow the contractor rules: a missing identifierType is inferred (a VAT UE number given in nip is stored as vatEu in vatUE) and reported in data.warnings; contradictions (e.g. identifierType nip with DE123456789, vatEu with a PL or XI number, a NIP with a wrong check digit, idWew for a buyer) are rejected with 422 PARTY_IDENTIFIER_INVALID naming the field (buyer.nip, receiver.vatUE). Equal instalments: send paymentInstallmentsSplit { count, firstDate?, every? } and the API splits the final amount due to the grosz (the remainder on the last instalment) and stores ordinary paymentInstallments; instalments that cannot be made (or both paymentInstallments and paymentInstallmentsSplit) are rejected with 422 PAYMENT_INSTALLMENTS_INVALID. A document has at most one live correction: a new correction of a document that already has one is rejected with 409 CORRECTED_INVOICE_HAS_CORRECTION, whose message names the latest correction of the chain; the next change corrects that correction (correctedInvoiceId = its id), so its state before includes the earlier changes. In KSeF a correction of a correction names the original invoice (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)\n\nRequired scope: `documents:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"documentType\": \"FakturaVAT\",\n  \"issueDate\": \"2026-05-07\",\n  \"buyer\": {\n    \"nip\": \"5261040828\",\n    \"name\": \"Acme Corp Sp. z o.o.\",\n    \"street\": \"Marszałkowska 1\",\n    \"postalCode\": \"00-001\",\n    \"city\": \"Warszawa\",\n    \"country\": \"Polska\",\n    \"countryCode\": \"PL\"\n  },\n  \"products\": [\n    {\n      \"name\": \"Usługa programistyczna\",\n      \"unitOfMeasure\": \"szt.\",\n      \"quantity\": 1,\n      \"netPrice\": 100,\n      \"netValue\": 100,\n      \"grossValue\": 123,\n      \"amountOfVat\": 23,\n      \"vatRate\": 23\n    }\n  ],\n  \"paymentMethodId\": 6,\n  \"paymentStatusId\": 1,\n  \"paymentDeadlineDate\": \"2026-05-14\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "GET /documents/{id} — Get document details",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "One document by id, with computed totals, payment fields and KSeF state.\n\n**Wymagane uprawnienie (Scope)**: `documents:read`\n\nRequired scope: `documents:read`"
          },
          "response": []
        },
        {
          "name": "PUT /documents/{id} — Full update of an existing document",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Replaces all editable fields of a document. documentType is immutable and cannot be changed. Buyer can be referenced by buyerId or inline buyer object. Seller is always taken from user.company and cannot be overwritten. An order (Zamowienie) that already has advance invoices is locked: the update is rejected with 400 ORDER_HAS_ADVANCE_INVOICES. Partial payments (partialPayments) that do not fit the document are rejected with 422 PARTIAL_PAYMENTS_INVALID. A buyer or receiver given as data follows the contractor identifier rules like on create (inferred identifierType reported in data.warnings, 422 PARTY_IDENTIFIER_INVALID on a contradiction); identifiers equal to the stored ones are not re-checked. paymentInstallmentsSplit splits the amount due of the document as it will be saved (the stored amount when products are not sent) into equal paymentInstallments, the remainder on the last one; 422 PAYMENT_INSTALLMENTS_INVALID when they cannot be made.\n\n**Wymagane uprawnienie (Scope)**: `documents:update`\n\n**Emitowane Webhooki**:\n- `document.updated` (na statusach: 200)\n\nRequired scope: `documents:update`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"issueDate\": \"2026-09-26\",\n  \"buyerId\": \"681a3b2c4d5e6f7a8b9c0d1e\",\n  \"products\": [\n    {\n      \"name\": \"Usługa programistyczna\",\n      \"unitOfMeasure\": \"godz.\",\n      \"quantity\": 10,\n      \"netPrice\": 150,\n      \"vatRate\": 23\n    }\n  ],\n  \"paymentMethodId\": 6,\n  \"paymentStatusId\": 1,\n  \"paymentDeadlineDate\": \"2026-10-10\",\n  \"comments\": \"Zamówienie #10234\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "PATCH /documents/{id} — Partial update of a document field(s)",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Updates only the provided fields of a document. All fields are optional — send only what needs to change. documentType is immutable and cannot be changed. Seller is always taken from user.company and cannot be overwritten. An order (Zamowienie) that already has advance invoices is locked: the update is rejected with 400 ORDER_HAS_ADVANCE_INVOICES. Partial payments (partialPayments) that do not fit the document are rejected with 422 PARTIAL_PAYMENTS_INVALID. A buyer or receiver given as data follows the contractor identifier rules like on create (inferred identifierType reported in data.warnings, 422 PARTY_IDENTIFIER_INVALID on a contradiction); identifiers equal to the stored ones are not re-checked. paymentInstallmentsSplit splits the amount due of the document as it will be saved (the stored amount when products are not sent) into equal paymentInstallments, the remainder on the last one; 422 PAYMENT_INSTALLMENTS_INVALID when they cannot be made.\n\n**Wymagane uprawnienie (Scope)**: `documents:update`\n\n**Emitowane Webhooki**:\n- `document.updated` (na statusach: 200)\n\nRequired scope: `documents:update`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"paymentDeadlineDate\": \"2026-10-24\",\n  \"comments\": \"Termin wydłużony na prośbę klienta\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "DELETE /documents/{id} — Delete a document",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Deletes a document that is not in KSeF. A document confirmed in KSeF (KSEF_CONFIRMED) or awaiting confirmation (KSEF_SENT) cannot be deleted; issue a correction instead. Linked documents are protected like in the app: an invoice that has a correction (409 DOCUMENT_CORRECTED), an advance invoice settled by a settlement invoice (409 ADVANCE_INVOICE_SETTLED) and an order with advance invoices (400 ORDER_HAS_ADVANCE_INVOICES). Deleting a warehouse document (WZ, PZ, PW, RW, MM) reverses its stock movements; deleting the last correction unlocks the corrected invoice.\n\n**Wymagane uprawnienie (Scope)**: `documents:delete`\n\n**Emitowane Webhooki**:\n- `document.deleted` (na statusach: 200)\n\nRequired scope: `documents:delete`"
          },
          "response": []
        },
        {
          "name": "GET /documents/{id}/download — Download document",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}/download",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id",
                "download"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Renders the PDF of a document. When the rendering queue is full the API answers 429 WAIT_PDF_QUEUE with Retry-After; retry after that many seconds.\n\n**Wymagane uprawnienie (Scope)**: `documents:download`\n\n**Limit zapytań**: 5 / 60 s\n\nRequired scope: `documents:download`"
          },
          "response": []
        },
        {
          "name": "POST /documents/validate — Dry-run validation of a document payload (no DB writes)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/documents/validate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                "validate"
              ]
            },
            "description": "Runs full validation pipeline and returns a preview (next number, resolved buyer/receiver, totals) without saving. Same scope as create. The preview lists the instalments that will be saved (paymentInstallments), also those computed from paymentInstallmentsSplit. Identifiers of a buyer or receiver given as data follow the contractor rules: a missing identifierType is inferred (a VAT UE number given in nip is stored as vatEu in vatUE) and reported in data.warnings; contradictions (e.g. identifierType nip with DE123456789, vatEu with a PL or XI number, a NIP with a wrong check digit, idWew for a buyer) are rejected with 422 PARTY_IDENTIFIER_INVALID naming the field (buyer.nip, receiver.vatUE).\n\n**Wymagane uprawnienie (Scope)**: `documents:create`\n\n**Limit zapytań**: 30 / 60 s\n\nRequired scope: `documents:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"documentType\": \"FakturaVAT\",\n  \"issueDate\": \"2026-05-07\",\n  \"buyer\": {\n    \"nip\": \"5261040828\",\n    \"name\": \"Acme Corp Sp. z o.o.\",\n    \"street\": \"Marszałkowska 1\",\n    \"postalCode\": \"00-001\",\n    \"city\": \"Warszawa\",\n    \"country\": \"Polska\",\n    \"countryCode\": \"PL\"\n  },\n  \"products\": [\n    {\n      \"name\": \"Usługa programistyczna\",\n      \"unitOfMeasure\": \"szt.\",\n      \"quantity\": 1,\n      \"netPrice\": 100,\n      \"vatRate\": 23\n    }\n  ],\n  \"subDateHeaderId\": 2,\n  \"paymentMethodId\": 6,\n  \"paymentStatusId\": 1,\n  \"paymentDeadlineDate\": \"2026-05-14\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "PATCH /documents/{id}/payment-status — Update document payment status",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}/payment-status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id",
                "payment-status"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Updates payment receipt state for a document. Supported values: RECEIVED or NOT_RECEIVED. paymentDate (YYYY-MM-DD, optional) is the day the payment arrived, today in Poland when omitted; it cannot be in the future. For the cash method it is the day of the VAT tax point. Allowed only for documents with payment status \"Do zapłaty\" (payment.status=1) or documents imported from KSeF (source=ksef).\n\n**Wymagane uprawnienie (Scope)**: `documents:update-payment-status`\n\n**Emitowane Webhooki**:\n- `document.paymentStatusChanged` (na statusach: 200)\n\nRequired scope: `documents:update-payment-status`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"receivedPayment\": \"RECEIVED\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "PATCH /documents/{id}/external-reference — Link document with external order reference",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}/external-reference",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id",
                "external-reference"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Links a document with an order in an external system (shop, ERP), so it can be found with `GET /documents?onlyUnlinked=false` and recognised in webhooks.\n\n**Wymagane uprawnienie (Scope)**: `documents:update-external-reference`\n\n**Emitowane Webhooki**:\n- `document.updated` (na statusach: 200)\n\nRequired scope: `documents:update-external-reference`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"externalSource\": \"woocommerce\",\n  \"externalOrderId\": \"10234\",\n  \"externalOrderNumber\": \"#10234\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "DELETE /documents/{id}/external-reference — Remove external order reference from a document",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}/external-reference",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id",
                "external-reference"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Removes the external order link from a document.\n\n**Wymagane uprawnienie (Scope)**: `documents:update-external-reference`\n\n**Emitowane Webhooki**:\n- `document.updated` (na statusach: 200)\n\nRequired scope: `documents:update-external-reference`"
          },
          "response": []
        },
        {
          "name": "PATCH /documents/{id}/margin-purchases — Set purchase amounts of margin-scheme lines",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}/margin-purchases",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id",
                "margin-purchases"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Sets the purchase amount (`marginPurchaseValue`, gross, PLN) and the rate of the tax on the margin (`marginTaxRate`) of lines with `vatRate: \"marza\"`, by their position in `products`. They are the seller's data for the VAT register and JPK, not invoice content, so they can change also after the document was sent to KSeF or corrected (a travel agency learns its costs later; an invoice downloaded from KSeF never carries them). A key left out keeps the stored value, `null` clears it.\n\n**Wymagane uprawnienie (Scope)**: `documents:update`\n\n**Emitowane Webhooki**:\n- `document.updated` (na statusach: 200)\n\nRequired scope: `documents:update`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"lines\": [\n    {\n      \"index\": 0,\n      \"marginPurchaseValue\": 1500,\n      \"marginTaxRate\": 23\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "POST /documents/{id}/send-to-ksef — Send document to KSeF",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}/send-to-ksef",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id",
                "send-to-ksef"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Starts KSeF instant send for an existing document. API waits for immediate KSeF result (best effort). If KSeF is still processing, endpoint returns success payload with processing status and client should poll status endpoint or consume 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)\n\nRequired scope: `documents:send-to-ksef`\n\nThis request takes a JSON body. See the matching guide at https://developers.fakturnia.pl for the exact fields."
          },
          "response": []
        },
        {
          "name": "GET /documents/{id}/ksef-status — Get document KSeF send status",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}/ksef-status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id",
                "ksef-status"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Returns simplified KSeF status state to support polling after send-to-ksef.\n\n**Wymagane uprawnienie (Scope)**: `documents:read`\n\n**Limit zapytań**: 5 / 60 s\n\nRequired scope: `documents:read`"
          },
          "response": []
        },
        {
          "name": "GET /documents/{id}/history — Get the history of a document",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/documents/{id}/history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "documents",
                ":id",
                "history"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ],
              "query": [
                {
                  "key": "currentPage",
                  "value": "",
                  "description": "Page number, starting from 1",
                  "disabled": true
                },
                {
                  "key": "itemsPerPage",
                  "value": "",
                  "description": "Page size (default 20, max 100)",
                  "disabled": true
                }
              ]
            },
            "description": "Activity journal of one document, newest first: CREATE, UPDATE (with the field diff in `changes`), SENT_BY_EMAIL, DOWNLOAD, KSEF_SENT, KSEF_ERROR, PAYMENT_RECEIVED, PAYMENT_REVERTED, DELETE and links to advance or settlement invoices. Each entry says who acted (owner or employee) and, when recorded, where from (`origin`: external_api, app, import). Page-based.\n\n**Wymagane uprawnienie (Scope)**: `documents:read`\n\nRequired scope: `documents:read`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "clients",
      "item": [
        {
          "name": "GET /clients/ — Get list of clients",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/clients/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "clients"
              ],
              "query": [
                {
                  "key": "searchQuery",
                  "value": "",
                  "description": "Filter clients by name, NIP or email",
                  "disabled": true
                },
                {
                  "key": "itemsPerPage",
                  "value": "",
                  "description": "Number of clients per page (max 100)",
                  "disabled": true
                },
                {
                  "key": "currentPage",
                  "value": "",
                  "description": "Current page number (starting from 1)",
                  "disabled": true
                }
              ]
            },
            "description": "Paginated list of contractors. `searchQuery` matches name, NIP, e-mail, first and last name (case-insensitive).\n\n**Wymagane uprawnienie (Scope)**: `clients:browse`\n\n**Limit zapytań**: 10 / 30 s\n\nRequired scope: `clients:browse`"
          },
          "response": []
        },
        {
          "name": "POST /clients/ — Create a new client",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/clients/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "clients"
              ]
            },
            "description": "Adds a contractor. A company needs `name`, a person `firstName` and `lastName`; the identifier named by `identifierType` is required. identifierType: nip (Polish NIP, 10 digits with a check digit), vatEu (EU VAT number with its country prefix in vatUE, e.g. DE123456789; EL for Greece), other (country code and otherTaxIdentifier, e.g. US and 12-3456789), idWew (internal unit NIP-NNNNN), none (consumer). Without identifierType the API infers it (a VAT UE number given in nip is stored as vatEu in vatUE, the country taken from its prefix) and reports it in data.warnings. Contradictions (nip with DE123456789, vatEu with a PL or XI number, a NIP with a wrong length or check digit, other without a country, an unknown identifierType) or a malformed e-mail answer 422 VALIDATION_ERROR naming the field; a NIP already present in the account answers 409.\n\n**Wymagane uprawnienie (Scope)**: `clients:create`\n\n**Emitowane Webhooki**:\n- `client.created` (na statusach: 200)\n\nRequired scope: `clients:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"company\",\n  \"contractorType\": \"client\",\n  \"identifierType\": \"nip\",\n  \"name\": \"Acme Sp. z o.o.\",\n  \"nip\": \"5261040828\",\n  \"street\": \"Marszałkowska 1\",\n  \"postalCode\": \"00-001\",\n  \"city\": \"Warszawa\",\n  \"country\": \"Polska\",\n  \"countryCode\": \"PL\",\n  \"email\": \"biuro@acme.pl\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "GET /clients/{id} — Get client details",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/clients/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "clients",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "One contractor by id.\n\n**Wymagane uprawnienie (Scope)**: `clients:read`\n\nRequired scope: `clients:read`"
          },
          "response": []
        },
        {
          "name": "PUT /clients/{id} — Update an existing client",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/clients/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "clients",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Full replacement of a contractor (PUT): omitted optional fields are cleared. Same validation and identifier rules as on create (data.warnings reports an inferred identifierType or a moved number); identifiers and e-mail addresses are checked only when they differ from the stored ones.\n\n**Wymagane uprawnienie (Scope)**: `clients:update`\n\n**Emitowane Webhooki**:\n- `client.updated` (na statusach: 200)\n\nRequired scope: `clients:update`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"company\",\n  \"contractorType\": \"client\",\n  \"identifierType\": \"nip\",\n  \"name\": \"Acme Sp. z o.o.\",\n  \"nip\": \"5261040828\",\n  \"street\": \"Marszałkowska 1\",\n  \"postalCode\": \"00-001\",\n  \"city\": \"Warszawa\",\n  \"country\": \"Polska\",\n  \"countryCode\": \"PL\",\n  \"email\": \"biuro@acme.pl\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "DELETE /clients/{id} — Delete a client",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/clients/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "clients",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Removes a contractor from the address book. Documents already issued keep their own copy of the buyer data.\n\n**Wymagane uprawnienie (Scope)**: `clients:delete`\n\n**Emitowane Webhooki**:\n- `client.deleted` (na statusach: 200)\n\nRequired scope: `clients:delete`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "products",
      "item": [
        {
          "name": "GET /products/ — Get list of products",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/products/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "products"
              ],
              "query": [
                {
                  "key": "searchQuery",
                  "value": "",
                  "description": "Filter products by name",
                  "disabled": true
                },
                {
                  "key": "itemsPerPage",
                  "value": "",
                  "description": "Number of products per page (max 100)",
                  "disabled": true
                },
                {
                  "key": "currentPage",
                  "value": "",
                  "description": "Current page number (starting from 1)",
                  "disabled": true
                }
              ]
            },
            "description": "Paginated list of products and services. `searchQuery` matches the name.\n\n**Wymagane uprawnienie (Scope)**: `products:browse`\n\n**Limit zapytań**: 10 / 30 s\n\nRequired scope: `products:browse`"
          },
          "response": []
        },
        {
          "name": "POST /products/ — Create a new product",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/products/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "products"
              ]
            },
            "description": "Adds a product or service. Send the unit price (`netPrice` or `grossPrice`) and `vatRate`; net value, VAT amount and gross value are computed to the cent.\n\n**Wymagane uprawnienie (Scope)**: `products:create`\n\n**Emitowane Webhooki**:\n- `product.created` (na statusach: 200)\n\nRequired scope: `products:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Usługa programistyczna\",\n  \"unitOfMeasure\": \"szt.\",\n  \"quantity\": 1,\n  \"netPrice\": 100,\n  \"vatRate\": 23,\n  \"currency\": \"PLN\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "GET /products/{id} — Get product details",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/products/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "products",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "One product by id.\n\n**Wymagane uprawnienie (Scope)**: `products:read`\n\nRequired scope: `products:read`"
          },
          "response": []
        },
        {
          "name": "PUT /products/{id} — Update an existing product",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/products/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "products",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Full replacement of a product (PUT). A new `netPrice` (or `vatRate`, `quantity`, `discount`) sent without `netValue`, `amountOfVat` and `grossValue` recomputes them to the cent, with the discount. Values sent explicitly are stored as sent only when they add up (net + VAT = gross), match the VAT rate and the price; otherwise 422 VALIDATION_ERROR names the field. When the price fields do not change, the stored product is not re-checked.\n\n**Wymagane uprawnienie (Scope)**: `products:update`\n\n**Emitowane Webhooki**:\n- `product.updated` (na statusach: 200)\n\nRequired scope: `products:update`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Usługa programistyczna (senior)\",\n  \"unitOfMeasure\": \"godz.\",\n  \"quantity\": 1,\n  \"netPrice\": 150,\n  \"vatRate\": 23,\n  \"currency\": \"PLN\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "DELETE /products/{id} — Delete a product",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/products/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "products",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Removes a product from the catalogue. Documents already issued keep their line items.\n\n**Wymagane uprawnienie (Scope)**: `products:delete`\n\n**Emitowane Webhooki**:\n- `product.deleted` (na statusach: 200)\n\nRequired scope: `products:delete`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "webhooks",
      "item": [
        {
          "name": "GET /webhooks/ — List webhooks",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhooks/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhooks"
              ],
              "query": [
                {
                  "key": "endpoint",
                  "value": "",
                  "description": "Optional endpoint URL to check if initial webhook exists.",
                  "disabled": true
                }
              ]
            },
            "description": "All webhooks of the account, newest first, without secrets. With `?endpoint=` the response also says whether a webhook for that URL exists (used by plugins that register themselves with POST /webhooks/initial).\n\n**Wymagane uprawnienie (Scope)**: `webhooks:read`\n\nRequired scope: `webhooks:read`"
          },
          "response": []
        },
        {
          "name": "POST /webhooks/ — Create a webhook",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/webhooks/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhooks"
              ]
            },
            "description": "Registers a public HTTPS endpoint for the chosen events. The signing secret is returned once, in this response only; rotate it with POST /webhooks/{id}/rotate-secret when lost. One webhook per endpoint URL.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:create`\n\nRequired scope: `webhooks:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"endpoint\": \"https://erp.example.com/hooks/fakturnia\",\n  \"events\": [\n    \"document.created\",\n    \"document.sentToKSeF\",\n    \"document.ksefRejected\"\n  ],\n  \"description\": \"ERP\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "POST /webhooks/initial — Create the initial webhook of a plugin (all events)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/webhooks/initial",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhooks",
                "initial"
              ]
            },
            "description": "Convenience endpoint for plugins: registers the endpoint for every event, idempotently per URL. Calling it again for the same URL returns `created: false`; with `rotateSecret: true` it issues a new secret. For a custom event subscription use POST /webhooks.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:create`\n\nRequired scope: `webhooks:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"endpoint\": \"https://shop.example.com/wp-json/fakturnia/v1/webhook\",\n  \"siteName\": \"Sklep Example\",\n  \"domain\": \"shop.example.com\",\n  \"rotateSecret\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "GET /webhooks/{id} — Get a webhook",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhooks/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhooks",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Returns one webhook with its delivery counters. The signing secret is never returned.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:read`\n\nRequired scope: `webhooks:read`"
          },
          "response": []
        },
        {
          "name": "PATCH /webhooks/{id} — Update a webhook",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/webhooks/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhooks",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Partial update: only the keys present in the body change. `events` replaces the whole subscription list. Setting `status` to ACTIVE re-enables a webhook switched off automatically after repeated failures and resets its failure streak.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:update`\n\nRequired scope: `webhooks:update`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"events\": [\n    \"document.created\",\n    \"document.paymentStatusChanged\"\n  ],\n  \"status\": \"ACTIVE\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "DELETE /webhooks/{id} — Delete a webhook",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhooks/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhooks",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Removes the webhook; pending deliveries are cancelled and no further events are sent to its endpoint.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:delete`\n\nRequired scope: `webhooks:delete`"
          },
          "response": []
        },
        {
          "name": "POST /webhooks/{id}/rotate-secret — Rotate the signing secret of a webhook",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhooks/{id}/rotate-secret",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhooks",
                ":id",
                "rotate-secret"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Generates a new secret and returns it once. Deliveries sent after this call are signed with the new secret, so update the receiver first, then rotate.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:update`\n\nRequired scope: `webhooks:update`\n\nThis request takes a JSON body. See the matching guide at https://developers.fakturnia.pl for the exact fields."
          },
          "response": []
        },
        {
          "name": "GET /webhooks/{id}/deliveries — List recent deliveries of a webhook",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhooks/{id}/deliveries",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhooks",
                ":id",
                "deliveries"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ],
              "query": [
                {
                  "key": "status",
                  "value": "",
                  "description": "Only deliveries in this state",
                  "disabled": true
                },
                {
                  "key": "currentPage",
                  "value": "",
                  "description": "Page number, starting from 1",
                  "disabled": true
                },
                {
                  "key": "itemsPerPage",
                  "value": "",
                  "description": "Page size (default 20, max 100)",
                  "disabled": true
                }
              ]
            },
            "description": "Newest first, page-based. Use it to debug a receiver: each row shows the event, the attempt count, the next retry and the last error. Delivery records are kept for 30 days.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:read`\n\nRequired scope: `webhooks:read`"
          },
          "response": []
        },
        {
          "name": "POST /webhooks/{id}/test — Send a test delivery to a webhook",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/webhooks/{id}/test",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhooks",
                ":id",
                "test"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Delivers a `webhook.test` event to the endpoint right away, signed like a real delivery, and reports the HTTP outcome. The ping is sent regardless of the subscribed events, is never retried and does not count towards the automatic switch-off.\n\n**Wymagane uprawnienie (Scope)**: `webhooks:update`\n\n**Limit zapytań**: 5 / 60 s\n\nRequired scope: `webhooks:update`\n\nThis request takes a JSON body. See the matching guide at https://developers.fakturnia.pl for the exact fields."
          },
          "response": []
        }
      ]
    },
    {
      "name": "ksef",
      "item": [
        {
          "name": "GET /ksef/connection — Get KSeF connection status",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/ksef/connection",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "ksef",
                "connection"
              ]
            },
            "description": "State of the KSeF connection of the account: whether a KSeF token or a certificate is configured (`connectionType`, `hasToken`, `hasCertificate`) and authorized, the environment, permissions and the last error. Secrets are never returned.\n\n**Wymagane uprawnienie (Scope)**: `ksef:read`\n\nRequired scope: `ksef:read`"
          },
          "response": []
        },
        {
          "name": "POST /ksef/connection — Create or update KSeF connection (token or certificate)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/ksef/connection",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "ksef",
                "connection"
              ]
            },
            "description": "Stores (or replaces) the KSeF connection of the account. Two methods are supported: a KSeF token (`connectionType` TOKEN with `token`) or a KSeF certificate (`connectionType` CERTIFICATE with `certificateContent`, `privateKeyContent` and `privateKeyPassword`). A body with the certificate fields and no `connectionType` is a certificate connection. Saving one method replaces the other. Secrets are encrypted at rest and never returned. Run `POST /ksef/connection/test` afterwards to authorize.\n\n**Wymagane uprawnienie (Scope)**: `ksef:configure`\n\nRequired scope: `ksef:configure`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"connectionType\": \"TOKEN\",\n  \"token\": \"20260901-EC-1A2B3C4D5E-6F7A8B9C0D-E1|nip-5261040828|0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\n  \"environment\": \"test\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "DELETE /ksef/connection — Deactivate KSeF connection",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/ksef/connection",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "ksef",
                "connection"
              ]
            },
            "description": "Deactivates the KSeF connection and removes the stored credentials (KSeF token, or certificate and private key).\n\n**Wymagane uprawnienie (Scope)**: `ksef:configure`\n\nRequired scope: `ksef:configure`"
          },
          "response": []
        },
        {
          "name": "POST /ksef/connection/test — Test KSeF connection authorization and permissions",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/ksef/connection/test",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "ksef",
                "connection",
                "test"
              ]
            },
            "description": "Authenticates in KSeF with the stored credentials (KSeF token or certificate) and records the result on the connection. Answers 200 with `isAuthorized` false when KSeF rejects the credentials.\n\n**Wymagane uprawnienie (Scope)**: `ksef:test`\n\n**Limit zapytań**: 5 / 60 s\n\nRequired scope: `ksef:test`\n\nThis request takes a JSON body. See the matching guide at https://developers.fakturnia.pl for the exact fields."
          },
          "response": []
        }
      ]
    },
    {
      "name": "settings",
      "item": [
        {
          "name": "GET /settings/ — Get general and numbering settings",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/settings/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "settings"
              ]
            },
            "description": "General settings (date format, newsletter) and numbering settings (numbering type and format, document symbols), with the allowed options.\n\n**Wymagane uprawnienie (Scope)**: `settings:read`\n\nRequired scope: `settings:read`"
          },
          "response": []
        },
        {
          "name": "PATCH /settings/general — Update general settings (date format, newsletter)",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/settings/general",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "settings",
                "general"
              ]
            },
            "description": "Sets the date format printed on documents and the newsletter consent.\n\n**Wymagane uprawnienie (Scope)**: `settings:update`\n\nRequired scope: `settings:update`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"dateFormat\": \"dd.MM.yyyy\",\n  \"newsletter\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "PATCH /settings/numbering — Update numbering settings (type, format, symbols)",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/settings/numbering",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "settings",
                "numbering"
              ]
            },
            "description": "Sets the numbering type (monthly or yearly), the date pattern of document numbers and the symbol prefix per document type.\n\n**Wymagane uprawnienie (Scope)**: `settings:update`\n\nRequired scope: `settings:update`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"numberingType\": \"MONTH\",\n  \"numberingFormat\": \"/MM/YYYY\",\n  \"documentSymbols\": {\n    \"FakturaVAT\": \"FV/\",\n    \"FakturaKorygujaca\": \"KOR/\",\n    \"Zamowienie\": \"ZAM/\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "company",
      "item": [
        {
          "name": "GET /company/nip-lookup — Lookup company data in GUS by NIP",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/company/nip-lookup",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "company",
                "nip-lookup"
              ],
              "query": [
                {
                  "key": "nip",
                  "value": "",
                  "description": "Polish NIP number (10 digits) (required)",
                  "disabled": false
                }
              ]
            },
            "description": "Looks a Polish company up in the GUS register by NIP and returns its name and address: `company` as registered and `buyer` with contractor field names, ready to pass as the `buyer` of a document or the body of a new client.\n\n**Wymagane uprawnienie (Scope)**: `gus:company:read`\n\n**Limit zapytań**: 10 / 60 s\n\nRequired scope: `gus:company:read`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "dictionaries",
      "item": [
        {
          "name": "GET /dictionaries/ — Get static dictionaries (document types, payment methods, etc.)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/dictionaries/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "dictionaries"
              ]
            },
            "description": "Static dictionaries needed to build documents: document types, payment methods and statuses, VAT rates, GTU codes, margin procedures, VAT exemption types, currencies, countries and date headers. Only a valid token is required, no scope."
          },
          "response": []
        }
      ]
    },
    {
      "name": "activity",
      "item": [
        {
          "name": "GET /activity/ — Get the account activity feed",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/activity/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "activity"
              ],
              "query": [
                {
                  "key": "scope",
                  "value": "",
                  "description": "Which journals to include",
                  "disabled": true
                },
                {
                  "key": "before",
                  "value": "",
                  "description": "Cursor: only entries older than this ISO date-time (use `nextBefore` from the previous page)",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "",
                  "description": "Entries per page (default 30, max 100)",
                  "disabled": true
                },
                {
                  "key": "employeeId",
                  "value": "",
                  "description": "Only one employee (id) or only the owner account (`main`)",
                  "disabled": true
                },
                {
                  "key": "from",
                  "value": "",
                  "description": "Only entries at or after this ISO date-time",
                  "disabled": true
                },
                {
                  "key": "to",
                  "value": "",
                  "description": "Only entries at or before this ISO date-time",
                  "disabled": true
                },
                {
                  "key": "q",
                  "value": "",
                  "description": "Free text: employee name or document number",
                  "disabled": true
                }
              ]
            },
            "description": "Everything that happened on the account, newest first: document actions (created, updated, sent, paid, deleted), employee logins and account management, warehouse operations. Merges the journals of the owner and every employee. Cursor pagination: pass `nextBefore` of a page as `before` to get the next one. Filter by `scope`, `employeeId` (an id, or `main` for the owner alone), a `from`/`to` window and free text `q` (employee name or document number).\n\n**Wymagane uprawnienie (Scope)**: `activity:read`\n\nRequired scope: `activity:read`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "email-accounts",
      "item": [
        {
          "name": "GET /email-accounts/ — List connected email accounts",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/email-accounts/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "email-accounts"
              ]
            },
            "description": "Mailboxes connected in the app (SMTP, Gmail, Outlook) that documents are e-mailed from, default mailbox first. Read-only: connecting, verifying and editing a mailbox happens in the app. Secrets are never returned.\n\n**Wymagane uprawnienie (Scope)**: `email-accounts:browse`\n\nRequired scope: `email-accounts:browse`"
          },
          "response": []
        },
        {
          "name": "GET /email-accounts/{id} — Get a connected email account",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/email-accounts/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "email-accounts",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "One mailbox by id, with its verification state. Secrets are never returned.\n\n**Wymagane uprawnienie (Scope)**: `email-accounts:read`\n\nRequired scope: `email-accounts:read`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "employees",
      "item": [
        {
          "name": "GET /employees/permissions — Get the registry of available employee permissions",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/employees/permissions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "employees",
                "permissions"
              ]
            },
            "description": "Registry of employee permissions (key, group, label, description, implied permissions). Only a valid token is required."
          },
          "response": []
        },
        {
          "name": "GET /employees/ — Get list of employee accounts",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/employees/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "employees"
              ]
            },
            "description": "Employee accounts of the owner, without passwords. Requires the MAX plan.\n\n**Wymagane uprawnienie (Scope)**: `employees:browse`\n\nRequired scope: `employees:browse`"
          },
          "response": []
        },
        {
          "name": "POST /employees/ — Create an employee account",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/employees/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "employees"
              ]
            },
            "description": "Creates an employee account (max 20 per account). The e-mail must be unique across Fakturnia. Requires the MAX plan.\n\n**Wymagane uprawnienie (Scope)**: `employees:create`\n\nRequired scope: `employees:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"firstName\": \"Jan\",\n  \"lastName\": \"Kowalski\",\n  \"emailAddress\": \"jan@firma.pl\",\n  \"password\": \"bardzo-tajne-haslo\",\n  \"permissions\": [\n    \"documents:read\",\n    \"documents:write\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "GET /employees/{id} — Get an employee account",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/employees/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "employees",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "One employee account by id, without the password.\n\n**Wymagane uprawnienie (Scope)**: `employees:browse`\n\nRequired scope: `employees:browse`"
          },
          "response": []
        },
        {
          "name": "PUT /employees/{id} — Update an employee account (data, permissions, activation, password)",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/employees/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "employees",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Updates an employee account: data, password, the full permission list, or `isActive` (false ends the sessions of the employee).\n\n**Wymagane uprawnienie (Scope)**: `employees:update`\n\nRequired scope: `employees:update`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"permissions\": [\n    \"documents:read\"\n  ],\n  \"isActive\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "DELETE /employees/{id} — Delete an employee account (soft delete; its email becomes available again)",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/employees/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "employees",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Deletes an employee account; its e-mail becomes available again.\n\n**Wymagane uprawnienie (Scope)**: `employees:delete`\n\nRequired scope: `employees:delete`"
          },
          "response": []
        },
        {
          "name": "GET /employees/{id}/activity — Get the activity feed of an employee",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/employees/{id}/activity",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "employees",
                ":id",
                "activity"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ],
              "query": [
                {
                  "key": "scope",
                  "value": "",
                  "description": "Which journals to include",
                  "disabled": true
                },
                {
                  "key": "before",
                  "value": "",
                  "description": "Cursor: only entries older than this ISO date-time (use `nextBefore` from the previous page)",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "",
                  "description": "Entries per page (default 30, max 100)",
                  "disabled": true
                }
              ]
            },
            "description": "What one employee did, newest first: logins (with device and IP), changes made to the account, document actions and warehouse operations. Cursor pagination: pass `nextBefore` of a page as `before` to get the next one; `scope` narrows to one journal.\n\n**Wymagane uprawnienie (Scope)**: `employees:browse`\n\nRequired scope: `employees:browse`"
          },
          "response": []
        }
      ]
    },
    {
      "name": "recurring-rules",
      "item": [
        {
          "name": "GET /recurring-rules/ — Get list of recurring document rules",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/recurring-rules/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "recurring-rules"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "",
                  "description": "Filter by rule status",
                  "disabled": true
                },
                {
                  "key": "currentPage",
                  "value": "",
                  "description": "Page number, starting from 1",
                  "disabled": true
                },
                {
                  "key": "itemsPerPage",
                  "value": "",
                  "description": "Page size (default 50, max 100)",
                  "disabled": true
                }
              ]
            },
            "description": "Returns all recurring rules with a summary (counts per status, next scheduled generation, monthly recurring gross in PLN). Requires the MAX plan.\n\n**Wymagane uprawnienie (Scope)**: `recurring:browse`\n\nRequired scope: `recurring:browse`"
          },
          "response": []
        },
        {
          "name": "GET /recurring-rules/{id}/history — Get generation history of a recurring rule",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/recurring-rules/{id}/history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "recurring-rules",
                ":id",
                "history"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ],
              "query": [
                {
                  "key": "currentPage",
                  "value": "",
                  "description": "Page number, starting from 1",
                  "disabled": true
                },
                {
                  "key": "itemsPerPage",
                  "value": "",
                  "description": "Page size (default 50, max 200)",
                  "disabled": true
                }
              ]
            },
            "description": "Journal of rule occurrences (newest first) with links to generated documents. Statuses: GENERATED, DRAFT, REMINDED, SKIPPED, FAILED, PENDING. Page-based (`currentPage`, `itemsPerPage`).\n\n**Wymagane uprawnienie (Scope)**: `recurring:read`\n\nRequired scope: `recurring:read`"
          },
          "response": []
        },
        {
          "name": "GET /recurring-rules/{id} — Get recurring rule details",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/recurring-rules/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "recurring-rules",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "One recurring rule with its schedule, automation and a summary of the generated document.\n\n**Wymagane uprawnienie (Scope)**: `recurring:read`\n\nRequired scope: `recurring:read`"
          },
          "response": []
        },
        {
          "name": "PATCH /recurring-rules/{id}/toggle — Pause or resume a recurring rule",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/recurring-rules/{id}/toggle",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "recurring-rules",
                ":id",
                "toggle"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Body: { \"active\": boolean }. Pausing clears nextRunAt (null while paused). Resuming recomputes nextRunAt from today: missed occurrences are NOT backfilled and an occurrence already generated today is not repeated. A FINISHED rule cannot be resumed (409).\n\n**Wymagane uprawnienie (Scope)**: `recurring:toggle`\n\nRequired scope: `recurring:toggle`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"active\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "warehouse",
      "item": [
        {
          "name": "GET /warehouse/ — Get list of warehouses",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/warehouse/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse"
              ]
            },
            "description": "All warehouses of the account.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:browse`\n\nRequired scope: `warehouse:browse`"
          },
          "response": []
        },
        {
          "name": "POST /warehouse/ — Create a warehouse (requires the MAX plan)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouse/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse"
              ]
            },
            "description": "Adds a warehouse. Requires the MAX plan.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:create`\n\nRequired scope: `warehouse:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Magazyn główny\",\n  \"symbol\": \"MAG1\",\n  \"address\": \"ul. Prosta 1, 00-001 Warszawa\",\n  \"isDefault\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "GET /warehouse/stock — Get stock levels report (sum of movements per product/warehouse)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/warehouse/stock",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse",
                "stock"
              ],
              "query": [
                {
                  "key": "asOf",
                  "value": "",
                  "description": "Historic stock state at the end of the given day (YYYY-MM-DD).",
                  "disabled": true
                },
                {
                  "key": "warehouseId",
                  "value": "",
                  "description": "Limit the report to a single warehouse.",
                  "disabled": true
                },
                {
                  "key": "productId",
                  "value": "",
                  "description": "Only this product",
                  "disabled": true
                }
              ]
            },
            "description": "Stock levels per product and warehouse, as the sum of movements. `asOf` returns the historical level at the end of that day, `warehouseId` narrows to one warehouse, `productId` to one product.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:stock:read`\n\nRequired scope: `warehouse:stock:read`"
          },
          "response": []
        },
        {
          "name": "GET /warehouse/movements — List stock movements",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/warehouse/movements",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse",
                "movements"
              ],
              "query": [
                {
                  "key": "productId",
                  "value": "",
                  "description": "Only movements of this product",
                  "disabled": true
                },
                {
                  "key": "warehouseId",
                  "value": "",
                  "description": "Only movements in this warehouse",
                  "disabled": true
                },
                {
                  "key": "documentId",
                  "value": "",
                  "description": "Only movements of this warehouse document",
                  "disabled": true
                },
                {
                  "key": "type",
                  "value": "",
                  "description": "Movement type or a comma-separated list",
                  "disabled": true
                },
                {
                  "key": "dateFrom",
                  "value": "",
                  "description": "Movement date from, inclusive (YYYY-MM-DD)",
                  "disabled": true
                },
                {
                  "key": "dateTo",
                  "value": "",
                  "description": "Movement date to, inclusive (YYYY-MM-DD)",
                  "disabled": true
                },
                {
                  "key": "currentPage",
                  "value": "",
                  "description": "Page number, starting from 1",
                  "disabled": true
                },
                {
                  "key": "itemsPerPage",
                  "value": "",
                  "description": "Page size (default 50, max 100)",
                  "disabled": true
                }
              ]
            },
            "description": "The stock ledger, newest first: every receipt and issue with its document, quantity, unit cost and who recorded it. Stock levels are the sum of these lines. Filter by product, warehouse, document, movement type (PZ, WZ, PW, RW, MM_OUT, MM_IN, INW, WYCENA) and a date range. Page-based.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:stock:read`\n\nRequired scope: `warehouse:stock:read`"
          },
          "response": []
        },
        {
          "name": "POST /warehouse/adjustments — Create a manual stock adjustment (INW movement)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouse/adjustments",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse",
                "adjustments"
              ]
            },
            "description": "Records a manual stock adjustment (inventory count, opening balance) as an INW movement. Positive quantity receives, negative issues. quantity 0 with unitCost is a revaluation (WYCENA movement): a new average cost of the current stock without changing the quantity; quantity 0 without unitCost is rejected (422).\n\n**Wymagane uprawnienie (Scope)**: `warehouse:adjust`\n\nRequired scope: `warehouse:adjust`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"productId\": \"681a3b2c4d5e6f7a8b9c0d1e\",\n  \"warehouseId\": \"681a3b2c4d5e6f7a8b9c0d1f\",\n  \"quantity\": 25,\n  \"unitCost\": 12.5,\n  \"date\": \"2026-09-26\",\n  \"note\": \"Bilans otwarcia\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "POST /warehouse/wz-from-invoice/{id} — Create a WZ document from a sales invoice (goods lines only)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouse/wz-from-invoice/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse",
                "wz-from-invoice",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Issues a WZ (goods issue) document for the goods lines of a sales invoice. Service lines and products without a catalogue entry are skipped. One WZ per invoice (409 on a duplicate). The WZ gets the account defaults of a warehouse document (WZ symbol and numbering, place of issue, comments, signatures, two-step release status), the recipient from the invoice, and is linked to the invoice on both sides (the WZ number is printed on the invoice and sent to KSeF). Missing goods are rejected with 422 STOCK_SHORTAGE unless allowNegativeStock=true; an unknown warehouse with 422 WAREHOUSE_INVALID.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:wz:create`\n\nRequired scope: `warehouse:wz:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"warehouseId\": \"681a3b2c4d5e6f7a8b9c0d1f\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "POST /warehouse/documents/validate — Validate a warehouse document without saving it",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouse/documents/validate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse",
                "documents",
                "validate"
              ]
            },
            "description": "Dry run of POST /warehouse/documents: full validation, the number the document would get, warehouses, lines resolved from the catalogue, stock before and after per line and the shortages that would block an outbound document. Nothing is written (a new contractor given as an object is not created). Requires the MAX plan.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:documents:create`\n\nRequired scope: `warehouse:documents:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"documentType\": \"PZ\",\n  \"issueDate\": \"2026-09-26\",\n  \"buyerId\": \"681a3b2c4d5e6f7a8b9c0d2e\",\n  \"products\": [\n    {\n      \"productId\": \"681a3b2c4d5e6f7a8b9c0d1e\",\n      \"quantity\": 20,\n      \"netPrice\": 45.5\n    }\n  ],\n  \"comments\": \"Dostawa do magazynu głównego\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "POST /warehouse/documents — Issue a warehouse document (WZ, PZ, PW, RW, MM)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouse/documents",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse",
                "documents"
              ]
            },
            "description": "Issues a warehouse document and books its stock movements. Lines reference catalogue products (productId); names, units and prices come from the catalogue unless given (PZ/PW: purchase price, WZ/RW/MM: sale price). WZ/PZ take a contractor in buyerId/buyer (WZ: recipient, PZ: supplier); PW/RW/MM have none. Missing warehouse = the default warehouse (MM: source = default, target required). Account defaults apply like in the app editor: symbol and numbering, place of issue, comments, signatures from the warehouse signature setting, stock status from the two-step release setting (useAccountDefaults=false switches them off). Outbound documents (WZ, RW, MM) that would take stock below zero are rejected with 422 STOCK_SHORTAGE unless allowNegativeStock=true. WZ with sourceInvoiceId is linked to the invoice on both sides (its number is printed on the invoice). Requires the MAX plan.\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)\n\nRequired scope: `warehouse:documents:create`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"documentType\": \"PZ\",\n  \"issueDate\": \"2026-09-26\",\n  \"buyerId\": \"681a3b2c4d5e6f7a8b9c0d2e\",\n  \"products\": [\n    {\n      \"productId\": \"681a3b2c4d5e6f7a8b9c0d1e\",\n      \"quantity\": 20,\n      \"netPrice\": 45.5\n    }\n  ],\n  \"comments\": \"Dostawa do magazynu głównego\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "GET /warehouse/{id} — Get a warehouse",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/warehouse/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "One warehouse by id.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:browse`\n\nRequired scope: `warehouse:browse`"
          },
          "response": []
        },
        {
          "name": "PUT /warehouse/{id} — Update a warehouse",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/warehouse/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Full replacement of a warehouse (PUT).\n\n**Wymagane uprawnienie (Scope)**: `warehouse:update`\n\nRequired scope: `warehouse:update`",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Magazyn główny\",\n  \"symbol\": \"MAG1\",\n  \"address\": \"ul. Prosta 1, 00-001 Warszawa\",\n  \"isDefault\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "DELETE /warehouse/{id} — Delete a warehouse (blocked when it has stock movements)",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/warehouse/{id}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "warehouse",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "<id>",
                  "description": "id path parameter"
                }
              ]
            },
            "description": "Removes a warehouse. Refused (409) when it still has stock movements or is the only warehouse of the account.\n\n**Wymagane uprawnienie (Scope)**: `warehouse:delete`\n\nRequired scope: `warehouse:delete`"
          },
          "response": []
        }
      ]
    }
  ]
}
