Fakturnia Developers Quickstart API reference Polski

History and activity

Everything that happens on the account is journaled: who issued a document, when it went out by e-mail, whether KSeF accepted it, who marked the payment, which movements passed through the warehouse, when an employee logged in. Through the API you read those journals in four ways, depending on the question.

Question Endpoint Scope Pagination
What happened to this document? GET /documents/{id}/history documents:read pages
What happened on the account today? GET /activity activity:read cursor
What did this employee do? GET /employees/{id}/activity employees:browse cursor
Which movements went through the warehouse? GET /warehouse/movements warehouse:stock:read pages

The journals are read-only and cover actions from every source: the API, the web and mobile apps, automations (recurring documents, the KSeF queue). The history of recurring rules is described in Recurring documents, webhook delivery history in Webhooks.

Document history

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": "Order #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
  }
}

Entry types: CREATE, UPDATE (with the field diff in changes), DELETE, SENT_BY_EMAIL (recipients in 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 (downloaded by the recipient from a link). actor says whether the owner or an employee acted, and origin (when the entry records it) where the action came from: external_api, app or import. channel is mcp when an AI assistant connected through the MCP server acted, and channelLabel then names its credential (e.g. Claude, ChatGPT or a key label); in other entries both fields are null.

The endpoint is paginated like the lists (Pagination): currentPage, itemsPerPage (up to 100), with totalCount and totalPages in the response.

Account activity

GET /activity merges the three journals of the whole account (the owner and every employee): document actions, employee logins and account changes, warehouse operations. Entries come newest first.

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"
  }
}

Filters:

Parameter Meaning
scope all (default), documents, auth (logins), management (employee account changes), warehouse
employeeId only one employee (id) or main (only the owner account)
from, to time window (ISO 8601)
q text: employee name or document number
limit entries per page, default 30, max 100
before cursor: nextBefore from the previous page

In the response, scope document covers document actions (with entityDeleted: true when the document was deleted later), warehouse covers warehouse operations (warehouse created, stock adjustment, warehouse documents), auth and management concern employee accounts.

Employee activity

GET /employees/{id}/activity returns the same shape as GET /activity, limited to one employee account, plus an employee object (as in GET /employees/{id}). It accepts scope, before and limit. An employee of another account answers 404.

Stock movements

GET /warehouse/movements is the ledger the stock levels are computed from: every receipt and issue with its document, quantity, unit cost and the person who recorded it. Filters: productId, warehouseId, documentId, type (comma-separated list: PZ, WZ, PW, RW, MM_OUT, MM_IN, INW, WYCENA), dateFrom / dateTo (YYYY-MM-DD). Paginated like the lists (itemsPerPage up to 100, default 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": "Opening balance", "employeeId": null, "employeeName": null, "createdAt": "2026-09-01T08:00:00.000Z" }
    ],
    "currentPage": 1, "itemsPerPage": 50, "totalCount": 2, "totalPages": 1
  }
}

The level of a product on a day is the sum of movements up to that day; GET /warehouse/stock?productId=…&asOf=… gives the same answer without walking the ledger. Module details: Warehouse.

Two styles of pagination

Resource lists and the document history are paginated by page number (currentPage, itemsPerPage, totalCount, totalPages): you know how much there is and can jump to any page. Activity streams (GET /activity, GET /employees/{id}/activity) merge several journals, so they use a time cursor: take nextBefore from a response and pass it as before until hasMore is false. New entries that arrive in the meantime do not shift the following pages. before is strict, though (it returns entries older than the given time), so entries with exactly the same timestamp, to the millisecond, as the last entry of a page can be skipped on the next page.