Skip to main content
Use the History API to access a full, paginated log of every change made in your Fibery workspace. Common use cases include:
  • Building custom audit trails and compliance reports
  • Generating activity digests or changelogs (“what changed this week?”)
  • Debugging automation behavior by inspecting what triggered a change
  • Powering external change-notification workflows
This API does not include changes to Documents content (rich text fields).

POST /api/history/v2/search

Returns a paginated list of workspace history entries matching the given filters.

Request body

Parameters

ParameterRequiredDescription
whereNoArray of filter objects. All filters are combined with logical AND. Pass [] for no filters.
timeframeNoDate range to search. Maximum span is 1 year. If omitted, defaults to last 30 days. Values are ISO 8601 datetime strings in UTC.
limitYesNumber of items per page. The API may return fewer items than requested even when more pages exist — always check nextPage.hasNext.
excludeAutomaticChangesNoSpecifies which types of automatic changes to exclude from processing.
sinceItemNoID of the last item from the previous page. Pass this to retrieve the next page.

Sample request

{
  "where": [
    {
      "field": "typeId",
      "operator": "=",
      "value": "{database-uuid}"
    },
    {
      "field": "action",
      "operator": "in",
      "value": [
        "fibery.entity/create",
        "fibery.entity/delete"
      ]
    }
  ],
  "timeframe": {
    "start": "{start-datetime}",
    "end": "{end-datetime}"
  },
  "excludeAutomaticChanges": [
    "automations",
    "integrations",
    "formulas",
    "auto-linking"
  ],
  "limit": 50,
  "sinceItem": "{since-item-id}"
}

Filters (where)

FieldDescriptionOperatorsValue
idHistory entry ID= inNumber
actionKind of change performed= inSee action values below
entityPublicIdEntity short public ID= inString
entityStateCurrent state of the entity= inEXIST DELETED ARCHIVED
authorUser who made the change= in empty not-emptyUser UUID. For empty/not-empty, omit the value key entirely.
typeIdDatabase ID — returns entity changes only, no schema changes= inDatabase UUID
entityTypeIdDatabase ID — returns entity changes and all related schema changes= inDatabase UUID
entityNameEntity name (partial match)containsText (minimum 3 characters)
entityIdEntity UUID= inUUID
fieldExclude specific field types from resultsnot-inSee field filter section below

Available action values:

  • fibery.entity/create
  • fibery.entity/delete
  • fibery.entity/update
  • fibery.entity/add-collection-items
  • fibery.entity/remove-collection-items
  • history/fibery.entity/archived
  • history/fibery.entity/restored
  • history/permissions-changed

The field filter (not-in):

Use this filter to exclude noisy system-generated changes and get a clean log of meaningful, human-made edits. It supports specific field names and wildcard aliases:
AliasWhat it excludes
:hiddenAll hidden fields
:privateAll private fields
:deletedAll deleted fields
:createdByCreated-by fields
:systemAll system fields
:nameAll title fields
Example — exclude hidden fields and rank fields:
{
  "field": "field",
  "operator": "not-in",
  "value": [
    {
      "field": ":hidden",
      "options": {
        "includeSoftDeleted": true
      }
    },
    {
      "field": "fibery/rank"
    },
    {
      "field": "fibery/menu-rank"
    },
    {
      "type": "Collaboration~Documents/Document"
    },
    {
      "type": "fibery/rich-text"
    },
    {
      "field": "fibery/public-id"
    },
    {
      "field": ":createdBy"
    }
  ]
}

Exclude automatic changes (excludeAutomaticChanges)

Use this option to exclude noisy changes made by system automatically
AliasWhat it excludes
integrationsAll integration changes
automationsChanges made by automation rules
auto-linkingAutomatically linked relations
formulasAll formula fields

Response body

Example response

{
  "items": [
    {
      "id": "120659039",
      "action": "fibery.entity/update",
      "date": "{ISO 8601 datetime}",
      "schemaVersion": 22782,
      "sequenceId": "18740668",
      "type": {
        "id": "1e1d96c0-5dcb-11e8-90b6-c6e140253257",
        "name": "Product Management/feature",
        "title": "Feature",
        "exist": true,
        "softDeleted": false
      },
      "entity": {
        "id": "d7cea490-354d-11eb-9bfa-a53706ca0a40",
        "name": "History API",
        "exist": true,
        "softDeleted": false,
        "publicId": "2797",
        "capabilities": {
          "restore": false
        }
      },
      "author": {
        "id": "79f2f29b-9a45-4e30-9ba6-b785f10c78ec",
        "name": "Eugene Kisel",
        "exist": true,
        "softDeleted": false,
        "publicId": "1210"
      },
      "order": "120659039",
      "fromService": null,
      "caller": null,
      "changedValues": [
        {
          "field": {
            "id": "56cba110-5dcb-11e8-90b6-c6e140253257",
            "name": "workflow/state",
            "title": "State"
          },
          "currentValue": {
            "id": "5715c970-5dcb-11e8-90b6-c6e140253257",
            "name": "In Progress"
          },
          "previousValue": {
            "id": "c9cfb7f0-a45d-11ec-b0b9-197891c72881",
            "name": "Next"
          }
        }
      ]
    }
  ],
  "nextPage": {
    "hasNext": true,
    "sinceItem": "120550073"
  }
}

items — array of history entries:

FieldDescription
idUnique ID of this history entry
actionThe type of change that was made
dateISO 8601 datetime of when the change occurred
schemaVersionWorkspace schema version at the time of the change — useful for correlating changes with schema migrations
sequenceIdMonotonically increasing event sequence ID — use this to establish ordering when processing events across pages
typeThe Database the changed entity belongs to (id, name, title)
entityThe entity that was changed (id, name, publicId, exist, softDeleted)
authorThe user who made the change. If null, the change was made by the system or an automation — see fromService.
fromServiceInternal Fibery service that triggered the change (set when author is null)
callerAdditional source information related to fromService
changedValuesList of field changes. Each item contains field (which field changed), currentValue (value after), and previousValue (value before).

nextPage — pagination metadata:

FieldDescription
hasNexttrue if more results exist on the next page
sinceItemPass this as sinceItem in the next request to retrieve the following page
hasNextLimitedtrue when a workspace plan limit has been reached. Upgrade the workspace to access further history entries.

Datetime format

All timeframe values must be ISO 8601 datetime strings in UTC.
BoundaryExample value
Start of a day (midnight)2026-03-01T00:00:00.000Z
End of a day (last millisecond)2026-03-01T23:59:59.999Z
Start of an hour2026-03-01T14:00:00.000Z
Start of a minute2026-03-01T14:30:00.000Z
The maximum allowed span between start and end is 1 year. For the “Get all changes from a specific day” sample below:
  • Replace {start-of-day} with midnight on your chosen date — e.g. 2026-03-01T00:00:00.000Z
  • Replace {end-of-day} with the last millisecond of that day — e.g. 2026-03-01T23:59:59.999Z
For all other samples, replace {start-datetime} and {end-datetime} with ISO 8601 values matching your desired range.

Query samples

Get all changes from a specific day

{
  "where": [],
  "timeframe": {
    "start": "{start-of-day}",
    "end": "{end-of-day}"
  },
  "limit": 50
}

Get changes to a specific Database

Replace {feature-type-uuid} with the Database UUID (find it in Database settings).
{
  "where": [
    {
      "field": "typeId",
      "operator": "=",
      "value": "{feature-type-uuid}"
    }
  ],
  "timeframe": {
    "start": "{start-datetime}",
    "end": "{end-datetime}"
  },
  "limit": 50,
  "sinceItem": "{next-page-since-item}"
}
To include schema changes (field additions, renames, deletions) alongside entity changes, replace typeId with entityTypeId.

Get all changes by a specific user

{
  "where": [
    {
      "field": "author",
      "operator": "=",
      "value": "{user-uuid}"
    }
  ],
  "timeframe": {
    "start": "{start-datetime}",
    "end": "{end-datetime}"
  },
  "limit": 50,
  "sinceItem": "{next-page-since-item}"
}

Get all changes to a specific entity

By entity UUID:
{
  "where": [
    {
      "field": "typeId",
      "operator": "=",
      "value": "{type-uuid}"
    },
    {
      "field": "entityId",
      "operator": "=",
      "value": "{entity-uuid}"
    }
  ],
  "timeframe": {
    "start": "{start-datetime}",
    "end": "{end-datetime}"
  },
  "limit": 50
}
By public ID (the short numeric ID shown in the Fibery UI):
{
  "where": [
    {
      "field": "typeId",
      "operator": "=",
      "value": "{type-uuid}"
    },
    {
      "field": "entityPublicId",
      "operator": "=",
      "value": "{entity-public-id}"
    }
  ],
  "timeframe": {
    "start": "{start-datetime}",
    "end": "{end-datetime}"
  },
  "limit": 50
}

Exclude automatic and system-generated changes

The log includes many system-generated changes by default (rank updates, formula recalculations, automation triggers). Use field not-in to filter them out:
{
  "where": [
    {
      "field": "field",
      "operator": "not-in",
      "value": [
        {
          "field": ":hidden",
          "options": { "includeSoftDeleted": true }
        },
        { "field": "fibery/rank" },
        { "field": "fibery/menu-rank" },
        { "type": "Collaboration~Documents/Document" },
        { "type": "fibery/rich-text" },
        { "field": "fibery/public-id" },
        { "field": ":createdBy" },
      ]
    }
  ],
  "excludeAutomaticChanges": ["integrations", "automations", "auto-linking", "formulas"],
  "timeframe": {
    "start": "{start-datetime}",
    "end": "{end-datetime}"
  },
  "limit": 50
}

Paginating through results

The API uses cursor-based pagination via sinceItem. To retrieve all pages:
  1. Make an initial request without sinceItem.
  2. If nextPage.hasNext is true, copy the value of nextPage.sinceItem.
  3. Pass it as sinceItem in the next request.
  4. Repeat until hasNext is false.
The API may return fewer items per page than your limit value, even when hasNext is true. This can happen when long-running internal tasks are interrupted mid-page. Always use hasNext to determine whether more results exist — do not assume the last page has been reached just because a partial result was returned.

Use cases

https://cdn.jsdelivr.net/gh/jdecked/twemoji@latest/assets/svg/2728.svg
Feel free to use the scripts below as is, fork them, or simply feed them to your coding agent as an example when working with History API.

Find maximum historical value of a Number Field

For each entity in a Database, get the maximum historical value of a certain Number Field. For example, understand what was the peak revenue for each customer. Here’s the solution overview (typed by a human):
  1. Filter entities to avoid querying everything in a Database (History API is quite slow by design).
  2. For each entity, find the Field’s maximum historical value.
  3. Write the results into a CSV file for manual inspection.
  4. Take the CSV file and update another Field with the maximum historical value for each entity.
And here’s the source code (co-created with AI): https://gitlab.com/fibery-community/api-examples/-/tree/master/extract-historical-max-value

Find when a Number Field value crossed a threshold

For each entity in a Database, understand when the value of a certain Number Field crossed a threshold. For example, for each Event, understand when the number of registrations crossed the 100 people mark — the point when an Event typically breaks even and is worth organizing. Here’s the solution:
  1. Find threshold crossings (e.g., when Subscription.Users became ≥ 2).
  2. Enrich them (if the Number Field is on Subscriptions DB but the Date Field should be on Workspaces DB, we have to to map IDs).
  3. Set the dates (→ Workspace.[Second Purchase Date]).
Source code in our community repo: https://gitlab.com/fibery-community/api-examples/-/tree/master/find-threshold-crossings-via-history