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
Parameter Required Description whereNo Array of filter objects. All filters are combined with logical AND. Pass [] for no filters. timeframeNo Date range to search. Maximum span is 1 year . If omitted, defaults to last 30 days. Values are ISO 8601 datetime strings in UTC. limitYes Number of items per page. The API may return fewer items than requested even when more pages exist — always check nextPage.hasNext. excludeAutomaticChangesNo Specifies which types of automatic changes to exclude from processing. sinceItemNo ID 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)
Field Description Operators Value idHistory entry ID = inNumber actionKind of change performed = inSee action values below entityPublicIdEntity short public ID = inString entityStateCurrent state of the entity = inEXIST DELETED ARCHIVEDauthorUser 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 results not-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:
Alias What 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
Alias What 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:
Field Description 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).
Field Description hasNexttrue if more results exist on the next pagesinceItemPass 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.
All timeframe values must be ISO 8601 datetime strings in UTC.
Boundary Example value Start of a day (midnight) 2026-03-01T00:00:00.000ZEnd of a day (last millisecond) 2026-03-01T23:59:59.999ZStart of an hour 2026-03-01T14:00:00.000ZStart of a minute 2026-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:
Make an initial request without sinceItem.
If nextPage.hasNext is true, copy the value of nextPage.sinceItem.
Pass it as sinceItem in the next request.
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
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):
Filter entities to avoid querying everything in a Database (History API is quite slow by design).
For each entity, find the Field’s maximum historical value.
Write the results into a CSV file for manual inspection.
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:
Find threshold crossings (e.g., when Subscription.Users became ≥ 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).
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