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.