Property changes
List Property Changes
Section titled “List Property Changes”Retrieves the property change history of one or more layer features. Every edit to a layer feature property is appended to this log, so it is the record of what changed, when, and by whom.
Endpoint: GET /propertyChanges
Authentication: Required (API Key)
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
layer_feature_id |
integer[] | Yes | Filter changes by one or more layer feature IDs (the id field of List Layer Features). At least one, at most 200. |
property_key |
string[] | No | Narrow the result to one or more property keys: a built-in property key (e.g. STATUS, ASSIGNEE) or a custom property definition UUID. Only narrows within layer_feature_id; cannot be used on its own. At most 200. |
_page |
integer | No | Page number (positive integer, defaults to 1) |
_pageSize |
integer | No | Number of changes per page (positive integer, defaults to 10, max 10,000) |
_sortBy |
string | No | Sort order. Format: +field (ascending) or -field (descending); repeat the parameter for tie-breaks. Sortable fields: created_at, id. Default: +created_at then +id (oldest first, see the ordering note below) |
There is deliberately no dataset_id filter: change history is always read per layer feature.
Note: in a URL a literal + decodes to a space, so an ascending _sortBy must be percent-encoded as %2B (_sortBy=%2Bcreated_at), or simply omitted since ascending is the default here.
Response Format
Section titled “Response Format”Returns a paginated response with the following structure:
{ "data": [ { "id": "uuid", "layer_feature_id": "integer", "property_key": "string", "new_value": "any | null", "system": "boolean", "user_id": "integer | null", "caused_by_change_id": "uuid | null", "created_at": "timestamp" } ], "pagination": { "rowCount": "integer", "pageCount": "integer", "page": "integer", "pageSize": "integer" }}Response Fields
Section titled “Response Fields”- id: UUID of the change
- layer_feature_id: Integer ID of the layer feature the change was made on
- property_key: The property that was changed. Either a built-in property key (e.g.
STATUS,ASSIGNEE,VOLUME), which is its own name and is not listed by List Property Definitions, or the UUID of a custom property definition, which you can resolve to a name via that endpoint. - new_value: The value the property was set to. Its type follows the property definition (string, number, boolean, array, …) and is
nullwhen the property was cleared. - system:
truewhen the change was made by the system rather than by a person. A system change never has auser_id. - user_id: Integer ID of the user who made the change, or
nullfor system changes - caused_by_change_id: UUID of the change that caused this one, when this change is a knock-on effect of another.
nullfor changes that were made directly. - created_at: ISO 8601 timestamp of when the change was made. This is supplied by the client that made the edit, so that edits made offline keep their real time.
- pagination: The standard pagination object.
rowCountcounts only the changes you are allowed to see.
Ordering: by default changes are returned oldest first, by created_at and then by id for changes that share a timestamp (a bulk edit stamps all of its changes with the same time). Because created_at comes from the client, a change recorded later can carry an earlier timestamp; it is sorted by that timestamp, not by when it reached the server. Because of this, a row that arrives while you are paging through +created_at can land in the middle of the order and shift the following pages, so a page walk may repeat or skip a row. To sweep a complete history reliably, page with _sortBy=%2Bid: id is assigned at insert time and increases with insertion order, so new rows only ever append. Use +created_at for display order.
Example Requests
Section titled “Example Requests”List the change history of a single layer feature:
curl -X GET "https://api.sitemark.com/propertyChanges?layer_feature_id=123&_pageSize=100" \ -H "Authorization: ApiKey your-api-key-here"List the change history of several layer features (with brackets):
curl -X GET "https://api.sitemark.com/propertyChanges?layer_feature_id[]=123&layer_feature_id[]=456" \ -H "Authorization: ApiKey your-api-key-here"Narrow to a single property:
curl -X GET "https://api.sitemark.com/propertyChanges?layer_feature_id=123&property_key=6f2f0e1a-2c4a-4f3e-9b62-0d1d0d0f9a11" \ -H "Authorization: ApiKey your-api-key-here"Newest first, second page:
curl -X GET "https://api.sitemark.com/propertyChanges?layer_feature_id=123&_sortBy=-created_at&_page=2&_pageSize=100" \ -H "Authorization: ApiKey your-api-key-here"Example Response
Section titled “Example Response”{ "data": [ { "id": "0193c0b6-1f3b-7a0e-9f2e-9c9b7b7a1c21", "layer_feature_id": 123, "property_key": "6f2f0e1a-2c4a-4f3e-9b62-0d1d0d0f9a11", "new_value": "IN_PROGRESS", "system": false, "user_id": 42, "caused_by_change_id": null, "created_at": "2026-01-15T09:12:44.000Z" }, { "id": "0193c0b6-1f3b-7a0e-9f2e-9c9b7b7a1c22", "layer_feature_id": 123, "property_key": "b1c2d3e4-5f60-4711-8899-aabbccddeeff", "new_value": null, "system": true, "user_id": null, "caused_by_change_id": "0193c0b6-1f3b-7a0e-9f2e-9c9b7b7a1c21", "created_at": "2026-01-15T09:12:44.000Z" } ], "pagination": { "rowCount": 2, "pageCount": 1, "page": 1, "pageSize": 10 }}Error Responses
Section titled “Error Responses”| Status Code | Description |
|---|---|
| 401 | Unauthorized - Invalid or missing API key |
| 400 | Bad Request - Missing layer_feature_id, more than 200 ids, an unsortable _sortBy field, or an unsupported parameter |
| 500 | Internal Server Error |
Note: Changes on layer features you do not have access to are left out of the response; they do not cause an error. Naming such a layer feature in layer_feature_id simply yields no rows for it.