Changelogs
API requests browser
Changelogs is an API available to administrators that lets you browse all API requests made on a site. It lets you filter by methods, path, and even see modifications to a specific path in the API.
Browsing changelogs
To browse the changelogs you can make a request to
GET
/changelogs
The summarized results show basic information about the affected path, the time, and a unique ID.
{
"path": "/api/vehicles/123",
"system_time": "2022-05-05T00:51:15.986524+00:00",
"user_id": "1",
"id": "ea975489-2fb6-4024-955b-011a9254ebfc",
"method": "PUT"
},
{
"path": "/api/vehicles",
"system_time": "2022-05-05T00:17:12.277080+00:00",
"user_id": "1",
"id": "40ae260c-9ef9-44ca-b7b7-4de175201b76",
"method": "POST"
},
User ID
Note that the User ID is a string because it can be a scoped user, with certain permissions.
"user_id": "user_id=16&write=vehicles,assets",
The full
param can be used to return detailed results of the request and response.
Filtering
Filtering is achieved with the following query params
query param | description | example |
---|---|---|
ids | List of unique IDs to search (note that when passed it shows the full results) | &ids=57f3845d-5727-48d2-839b-bad4c387945f |
user_ids | List of user IDs to filter for changes | &user_ids=1,2,3 |
methods | Methods to filter by | &methods=POST |
path | Specific path to search (accepts regex) | path=/api/vehicles |
Regex paths
The
path
parameter accepts regex to match multiple results.For example: matches any vehicle ID
&path=^/api/vehicles/?.*$
Filtering can also be achieved by using the results of the request or response. To do this you need to build a flattened key that points to the value you're searching for.
For example if the results of the changelogs are:
{
"system_time": "2022-04-29T06:59:03.564102+00:00",
"user_id": "60",
"request": {},
"response": {
"status": "200 OK",
"status_code": 200,
"data": {
"first_name": "John",
"email": "[email protected]",
"groups": [1,2,3],
"properties": {
"certified": true
},
"id": 123
}
}
}
You can target specific values by navigating the json fields in dot notation, starting from request
or response
.
query param | description |
---|---|
response.data.first_name=John | Filters results by all first_names = John |
response.data.groups.0=2 | Filters results whose groups array contains group ID 2 |
response.data.properties.types=[27] | Filters the first element in an array with a value of 27 |
response.data.properties.types.0=27 | Filters for any element in an array with a value of 27 |
response.data.properties.certified=true | Filters results by a custom property with a boolean true value |
response.data.id=123 | Filter results by the response ID (combined with method POST can be used to search creation of entities) |
Navigating changelogs
In order to navigate the changelogs you need to look at the values of total
and offset
.
The total gives you the total amount of results from the changelogs request, while offset indicates how far from the first result you must navigate to reach the total. Note that you navigate the changelogs until the count plus the offset equals the total.
query param | description |
---|---|
count | amount of results in changelogs request |
total | total number of changes to navigate through |
offset | number of results to skip until you reach the total |
// showing first 25 results (count) out of a total of 53
GET /changelogs?limit=25
{
"count": 25,
"query": {},
"total": 53,
"data": [],
"offset": 0
}
// showing next 25 results
GET /changelogs?limit=25&offset=25
{
"count": 25,
"query": {},
"total": 53,
"data": [],
"offset": 25
}
// showing last 3 results after applying an offset with the first 50
GET /changelogs?limit=25&offset=50
{
"count": 3,
"query": {},
"total": 53,
"data": [],
"offset": 50
}
Modifications
Modifications are specific changes done to the responses of certain resources within the API. You may want to browse whenever certain properties have changed over time, this API is useful for that.
Browsing modifications
To browse modifications you can make a GET request to
GET
/changelogs/modifications
The modifications occur over one of the following specific resources, which must be passed as a query param resource
:
- vehicles
- assets
- geofences
- geofence_types
Vehicle modifications request
GET/changelogs/modifications?resource=vehicles
This request essentially filters only PUTs made to the resource requested.
Filtering
You can filter the results to multiple resource IDs, or group IDs using the query params ids
& groups
query param | description | example |
---|---|---|
ids | List of resource IDs to search for | &ids=1,2,3 |
groups | List of group IDs to search for | &groups=1,2,3 |
You can also filter only specific changes to a resource using the query param changes
. This param allows you to filter when only specific fields within the resource change over time.
For example if you want to see the changes of a particular vehicle's property over time you can use:
&changes=properties.OrderNumber
The results will give you something like this
// GET /changelogs/modifications?resource=vehicles&ids=1&changes=properties.OrderNumber
{
"properties.OrderNumber": 8012635798,
"$$user_id": "3",
"$$id": "854fdd5b-330a-4632-b920-c6e43efc5158",
"$$system_time": "2022-05-03T21:27:03.369956+00:00",
"$$object": 1
},
{
"properties.OrderNumber": 8012635207,
"$$user_id": "3",
"$$id": "07818630-2f5a-4402-a5f7-46d35ea1e85b",
"$$system_time": "2022-05-03T19:21:15.476119+00:00",
"$$object": 1
},
Where the $$ fields refer to the user Id that made the change, the unique identifier for that changelog request, the time of the change, and the ID of the resource that was filtered.
Navigating modifications
In order to navigate modifications you have to keep in mind two things: pointer
& section
.
Pointer
The pointer indicates which changelog modifications are being traversed across the universe of all changes (notice that there's no total, this will become more clear later).
For every changelog modification response there's a key called next_pointer
that indicates how you should modify the pointer
param for the next set of modification changes. In a way the pointer
is similar to the changelog's offset
in that it can be moved, however it's different in that it depends on a value from the returned results to update (next_pointer
), and it's moved until the next_pointer
= -1
For example:
// Vehicle modifications for OrderNumber which returns a count of 6 results
// Since next_pointer = -1 these are all the possible results
GET /changelogs/modifications?resource=vehicles&ids=1&changes=properties.OrderNumber
{
"count": 6,
"query": {
"resource": "vehicles",
"pointer": 0,
"section": 1,
"ids": [
1
],
"to": "2022-05-03T23:59:59+00:00",
"limit": 100,
"from": "2022-05-03T00:00:00+00:00",
"changes": [
"properties.OrderNumber"
]
},
"data": [],
"next_pointer": -1,
"sections": 1
}
// Same vehicle modifications for OrderNumber which returns a count of 2 results since we limit it to 2
// Since next_pointer is != -1 our next request will have a pointer value = 10
GET /changelogs/modifications?resource=vehicles&ids=1&changes=properties.OrderNumber&limit=2
{
"count": 2,
"query": {
"resource": "vehicles",
"pointer": 0,
"section": 1,
"ids": [
1
],
"to": "2022-05-03T23:59:59+00:00",
"limit": 2,
"from": "2022-05-03T00:00:00+00:00",
"changes": [
"properties.OrderNumber"
]
},
"data": [],
"next_pointer": 10,
"sections": 1
}
// In our example the next pointer values increase to 21, 33, 41, before finally reaching -1
GET /changelogs/modifications?resource=vehicles&ids=1&changes=properties.OrderNumber&limit=2&pointer=21
GET /changelogs/modifications?resource=vehicles&ids=1&changes=properties.OrderNumber&limit=2&pointer=33
GET /changelogs/modifications?resource=vehicles&ids=1&changes=properties.OrderNumber&limit=2&pointer=41
// Once it reaches -1 we know we're done
Results when traversing multiple pages
Keep in mind that anytime you move a pointer to request more changelog modifications you're going to have repeated values where the last modification of one page is equal to the next modification of the next page.
Sections
The next thing to watch out for are the sections, these are large data sets that must be traversed to obtain all the results.
// Vehicle modifications for OrderNumber which returns 14 sections
// The first section must be traversed until next_pointer = -1
GET /changelogs/modifications?resource=vehicles&groups=123&changes=properties.OrderNumber
{
"count": 100,
"query": {
"resource": "vehicles",
"pointer": 0,
"section": 1,
"ids": [],
"to": "2022-05-03T08:30:00-04:00",
"limit": 100,
"from": "2022-05-03T00:00:00-04:00",
"changes": [
"properties.OrderNumber"
]
},
"data": [],
"next_pointer": 147,
"sections": 14
}
GET /changelogs/modifications?resource=vehicles&groups=123&changes=properties.OrderNumber&pointer=147
GET /changelogs/modifications?resource=vehicles&groups=123&changes=properties.OrderNumber&pointer=XXX...
// The last page of the first section may be
GET /changelogs/modifications?resource=vehicles&groups=123&changes=properties.OrderNumber&pointer=1034
{
"count": 23,
"query": {
"resource": "vehicles",
"pointer": 1034,
"section": 1,
"ids": [],
"to": "2022-05-03T08:30:00-04:00",
"limit": 100,
"from": "2022-05-03T00:00:00-04:00",
"changes": [
"properties.OrderNumber"
]
},
"data": [],
"next_pointer": -1,
"sections": 14
}
// At which point the next section must be traversed until you reach all sections
GET /changelogs/modifications?resource=vehicles&groups=123&changes=properties.OrderNumber&pointer=1034§ion=2
{
"count": 100,
"query": {
"resource": "vehicles",
"pointer": 0,
"section": 2,
"ids": [],
"to": "2022-05-03T08:30:00-04:00",
"limit": 100,
"from": "2022-05-03T00:00:00-04:00",
"changes": [
"properties.OrderNumber"
]
},
"data": [],
"next_pointer": 40,
"sections": 14
}
// Once your section = sections and next_pointer = -1 you've traversed all sections of all possible changes and you're done
Updated 11 months ago