Fakturnia Developers Szybki start Dokumentacja API English

Historia i aktywność

Wszystko, co dzieje się na koncie, zostaje w dziennikach: kto wystawił dokument, kiedy poszedł mailem, czy KSeF go przyjął, kto oznaczył zapłatę, jakie ruchy przeszły przez magazyn, kiedy logował się pracownik. Przez API czytasz te dzienniki na cztery sposoby, w zależności od tego, o co pytasz.

Pytanie Endpoint Scope Paginacja
Co się działo z tym dokumentem? GET /documents/{id}/history documents:read strony
Co się dzisiaj działo na koncie? GET /activity activity:read kursor
Co robił ten pracownik? GET /employees/{id}/activity employees:browse kursor
Jakie ruchy przeszły przez magazyn? GET /warehouse/movements warehouse:stock:read strony

Dzienniki są tylko do odczytu i obejmują akcje z każdego źródła: API, aplikacji web i mobilnej, automatów (dokumenty cykliczne, kolejka KSeF). Historię reguł cyklicznych opisuje Dokumenty cykliczne, historię dostaw webhooków Webhooki.

Historia dokumentu

curl -s "https://sandbox.api.fakturnia.pl/external/v1/documents/681a3b2c4d5e6f7a8b9c0d1e/history?itemsPerPage=20" \
  -H "Authorization: Bearer $TOKEN"
{
  "success": true,
  "data": {
    "documentId": "681a3b2c4d5e6f7a8b9c0d1e",
    "documentNumber": "FV/12/09/2026",
    "entries": [
      { "id": "681a…2a", "type": "PAYMENT_RECEIVED", "createdAt": "2026-09-26T12:00:00.000Z", "actor": "employee", "employeeId": "681a…3b", "employeeName": "Ewa Kowalska", "origin": "app", "channel": null, "channelLabel": null, "changes": null, "data": { "origin": "app", "receivedPayment": "RECEIVED" } },
      { "id": "681a…29", "type": "KSEF_SENT", "createdAt": "2026-09-26T11:05:00.000Z", "actor": "owner", "employeeId": null, "employeeName": null, "origin": null, "channel": null, "channelLabel": null, "changes": null, "data": { "ksefNumber": "5271012345-20260926-AABBCC-DD", "sendMode": "instant" } },
      { "id": "681a…28", "type": "UPDATE", "createdAt": "2026-09-26T10:40:00.000Z", "actor": "owner", "employeeId": null, "employeeName": null, "origin": null, "channel": null, "channelLabel": null, "changes": [{ "field": "comments", "oldValue": "", "newValue": "Zamówienie #10234" }], "data": null },
      { "id": "681a…27", "type": "CREATE", "createdAt": "2026-09-26T10:30:00.000Z", "actor": "owner", "employeeId": null, "employeeName": null, "origin": "external_api", "channel": null, "channelLabel": null, "changes": null, "data": { "origin": "external_api", "source": "local" } }
    ],
    "currentPage": 1, "itemsPerPage": 20, "totalCount": 4, "totalPages": 1
  }
}

Typy wpisów: CREATE, UPDATE (z różnicami pól w changes), DELETE, SENT_BY_EMAIL (adresaci w data), DOWNLOAD, DOWNLOAD_XML, DOWNLOAD_UPO, PRINT, KSEF_SENT, KSEF_ERROR, PAYMENT_RECEIVED, PAYMENT_REVERTED, ADVANCE_INVOICE_LINKED / UNLINKED, SETTLEMENT_INVOICE_LINKED / UNLINKED, DOWNLOAD_CLIENT (pobranie przez odbiorcę z linku). actor mówi, czy działał właściciel, czy pracownik, a origin (gdy wpis to zapisuje) skąd przyszła akcja: external_api, app albo import. channel ma wartość mcp, gdy akcję wykonał asystent AI połączony przez serwer MCP, a channelLabel podaje wtedy nazwę jego poświadczenia (np. Claude, ChatGPT albo etykietę klucza); w pozostałych wpisach oba pola mają wartość null.

Endpoint jest stronicowany jak listy (Paginacja): currentPage, itemsPerPage (do 100), w odpowiedzi totalCount i totalPages.

Aktywność konta

GET /activity łączy trzy dzienniki całego konta (właściciel i wszyscy pracownicy): akcje na dokumentach, logowania i zmiany kont pracowniczych, operacje magazynowe. Wpisy przychodzą od najnowszego.

curl -s "https://sandbox.api.fakturnia.pl/external/v1/activity?scope=documents&from=2026-09-26T00:00:00Z&limit=50" \
  -H "Authorization: Bearer $TOKEN"
{
  "success": true,
  "data": {
    "items": [
      { "id": "681a…1e", "scope": "document", "type": "CREATE", "createdAt": "2026-09-26T10:30:00.000Z", "employeeId": null, "employeeName": null, "entityId": "681a…1f", "entityName": "FV/12/09/2026", "entityType": "DOCUMENT", "entityDeleted": false, "changes": null, "data": { "origin": "external_api", "source": "local" } },
      { "id": "681a…1d", "scope": "auth", "type": "LOGIN", "createdAt": "2026-09-26T07:58:00.000Z", "employeeId": "681a…3b", "employeeName": "Ewa Kowalska", "entityId": null, "entityName": null, "entityType": null, "entityDeleted": false, "changes": null, "data": { "ip": "203.0.113.5", "device": "web" } }
    ],
    "hasMore": true,
    "nextBefore": "2026-09-26T07:58:00.000Z"
  }
}

Filtry:

Parametr Znaczenie
scope all (domyślnie), documents, auth (logowania), management (zmiany kont pracowniczych), warehouse
employeeId tylko jeden pracownik (id) albo main (tylko konto właściciela)
from, to okno czasowe (ISO 8601)
q tekst: imię i nazwisko pracownika albo numer dokumentu
limit wpisów na stronę, domyślnie 30, maksymalnie 100
before kursor: nextBefore z poprzedniej strony

scope document w odpowiedzi to akcje na dokumentach (w tym entityDeleted: true, gdy dokument został później usunięty), warehouse to operacje magazynowe (utworzenie magazynu, korekta stanu, dokumenty magazynowe), auth i management dotyczą kont pracowniczych.

Aktywność pracownika

GET /employees/{id}/activity zwraca ten sam kształt co GET /activity, ograniczony do jednego konta pracowniczego, oraz obiekt employee (jak w GET /employees/{id}). Przyjmuje scope, before i limit. Pracownik spoza konta odpowiada 404.

Ruchy magazynowe

GET /warehouse/movements to księga ruchów, z której liczą się stany: każde przyjęcie i wydanie z dokumentem, ilością, kosztem jednostkowym i osobą, która je zapisała. Filtry: productId, warehouseId, documentId, type (lista po przecinku: PZ, WZ, PW, RW, MM_OUT, MM_IN, INW, WYCENA), dateFrom / dateTo (YYYY-MM-DD). Stronicowanie jak w listach (itemsPerPage do 100, domyślnie 50).

curl -s "https://sandbox.api.fakturnia.pl/external/v1/warehouse/movements?productId=681a3b2c4d5e6f7a8b9c0d2a&dateFrom=2026-09-01" \
  -H "Authorization: Bearer $TOKEN"
{
  "success": true,
  "data": {
    "movements": [
      { "id": "681a…4c", "productId": "681a…2a", "warehouseId": "681a…3b", "quantity": -2, "unitCost": null, "type": "WZ", "documentId": "681a…4d", "documentNumber": "WZ/3/09/2026", "date": "2026-09-26", "note": null, "employeeId": null, "employeeName": null, "createdAt": "2026-09-26T10:30:00.000Z" },
      { "id": "681a…4b", "productId": "681a…2a", "warehouseId": "681a…3b", "quantity": 25, "unitCost": 12.5, "type": "INW", "documentId": null, "documentNumber": null, "date": "2026-09-01", "note": "Bilans otwarcia", "employeeId": null, "employeeName": null, "createdAt": "2026-09-01T08:00:00.000Z" }
    ],
    "currentPage": 1, "itemsPerPage": 50, "totalCount": 2, "totalPages": 1
  }
}

Stan produktu na dzień to suma ruchów do tego dnia; ten sam wynik da GET /warehouse/stock?productId=…&asOf=… bez przeglądania księgi. Szczegóły modułu: Magazyn.

Dwa style paginacji

Listy zasobów i historia dokumentu są stronicowane numerami stron (currentPage, itemsPerPage, totalCount, totalPages): wiesz, ile jest wszystkiego, i możesz skoczyć na dowolną stronę. Strumienie aktywności (GET /activity, GET /employees/{id}/activity) łączą kilka dzienników, więc używają kursora czasowego: bierzesz nextBefore z odpowiedzi i podajesz jako before, dopóki hasMore nie będzie false. Nowe wpisy, które dojdą w międzyczasie, nie przesuwają kolejnych stron. before działa jednak ostro (zwraca wpisy starsze niż podany czas), więc wpisy z dokładnie tym samym czasem co ostatni wpis strony, co do milisekundy, mogą zostać pominięte na następnej stronie.