Skip to main content

Reference: Changes & Activity

What changed, when, and who did it. This is the data behind the Change Tracking, Change Analysis and Activity Explorer pages. Scan pair and time window rules are in Conventions.

Which change route should I use?

  • getScanDiff compares two StratoLens scans exactly like the Changes page: ignore rules applied, role assignment changes included. Its counts match the UI.
  • getResourceGraphChanges and resource-changes-summary are raw Azure Resource Graph change events, with exact time and changer. They are not filtered by ignore rules and do not include role assignment changes.
  • The activity-log routes give Azure Activity Log operations, including role assignment (RBAC) activity and failed operations.

Scan Comparison

GET /api/getScanDiff

Permission: View Resources

Everything added, deleted or modified between two scans. Every page recomputes the whole diff, so prefer one unpaged call.

Parameters

getScanDiff parameters
NameRequiredNotes
baseScanId, compareScanIdyesScan pair: older, then newer
pageSizenoAbsent = the whole diff in one response (recommended). Present = up to 1000; 0, a negative or a non-numeric value means 100
continuationTokennoThe offset returned by the previous page. Read only when pageSize is also sent; without pageSize it is silently ignored and the whole diff is returned

Errors

  • 400Scan-pair errors (see Conventions). A 404 can also mean the scan has no inventory you can see
  • 400Invalid continuationToken '<tok>' - expected a non-negative integer offset.
  • 500An error occurred while processing the scan comparison.

Response: { summary, manifest, resources[], optimizationMetadata, pagination? }.

getScanDiff response fields
FieldMeaning
summary{ baseScanId, compareScanId, baseScanTime, compareScanTime, added, deleted, modified }. Counts cover the whole diff
manifestThe newer scan's summary record (see getScanResults)
resources[]One item per entity (below)
optimizationMetadata{ ignoreMetrics, ignoreRulesUsed[], ignoreRulesTimestamp }: what the installation's ignore rules suppressed
paginationOnly when pageSize was sent: { pageSize, continuationToken?, hasMore, totalResults }

resources[] item

getScanDiff resources item fields
FieldMeaning
id, name, type, location, resourceGroup, subscriptionId, subscriptionName, tenantId, tags, entityType, propertiesThe entity
rbacSummary, rbacAssignmentsRole assignments
changeStatusadded, deleted, modified, unchanged
changes[]{ property, before, after }, where property is one of name, entityName, location, subscriptionName, resourceGroup, properties, rbacAssignments, tags
diffTree?Nested property diff. Each node: { status: added | deleted | modified | nested, before?, after?, children?, isIgnored? }
hasIgnoredChanges?Changes hidden by ignore rules
hasChildChanges?, childChangeCounts?{ added, modified, deleted } for child resources

Notes

  • resources also contains every subscription and management group (even when unchanged) and resources whose only changes were ignored. Filter on changeStatus !== "unchanged" to get real changes.

Example

GET /api/getScanDiff?baseScanId=<older>&compareScanId=<newer>

Resource Graph Changes and Attribution

GET /api/getResourceGraphChanges

Permission: View Resource Changes

Raw Azure change events in a time window, newest first. Every page re-reads the whole window, so prefer narrower windows over deep offset walks.

Parameters

getResourceGraphChanges parameters
NameRequiredNotes
start, endyesTime window
subscriptionIdnoExact
resourceGroupName, resourceNamenoCase-insensitive
resourceIdnoAny case
entityTypenosubscription, resourceGroup, resource, managementGroup
managementGroupIdnoPlain management group name (not a path); used with entityType=managementGroup
limitno1-10000; default all
offsetno≥ 0; default 0

entityType rules: subscription returns only subscription-level events; resourceGroup needs resourceGroupName; resource needs resourceName + resourceGroupName; managementGroup needs managementGroupId. Without its companion parameter, the type filter is ignored.

Errors

  • 400GET requests require 'start' and 'end' query parameters
  • 400Time-window errors
  • 400limit must be an integer between 1 and 10000
  • 400offset must be a non-negative integer
  • 400entityType must be 'subscription', 'resourceGroup', 'resource', or 'managementGroup'
  • 500Failed to retrieve resource graph changes: <message>

Response: { changes[], totalCount, hasMore, limit, offset }. totalCount counts every match. Each change:

getResourceGraphChanges change fields
FieldMeaning
resourceId (lower-case), originalResourceId, resourceName?, resourceType?, resourceGroupName?, subscriptionId, subscriptionName?, entityType?, managementGroupId?, managementGroupName?What changed
changeTypeCreate, Update, Delete
changeTimeWhen
changedBy?UPN or app ID
userDisplayName?Resolved name
changedByType?, clientType?Who or what made the change
changedProperties[]Property paths that changed
beforeState?, afterState?Full resource snapshots
hasFullSnapshots?, snapshotDataSource?Snapshot provenance
correlationId?Links to Activity Log operations
activityMonthYYYY-MM

Notes

  • Ordered newest first, then by ID; offset walks are stable.

Example

GET /api/getResourceGraphChanges?start=2026-10-01T00:00:00Z&end=2026-10-14T23:59:59Z&subscriptionId=<guid>&limit=500

GET /api/resource-changes-summary

Permission: View Resource Changes

Change counts per entity, per change type and per user, for a window.

Parameters

resource-changes-summary parameters
NameRequiredNotes
start, endyesTime window
subscriptionIdno
resourceGroupNamenoNeeds subscriptionId

Errors

  • 400GET requests require 'start' and 'end' query parameters
  • 400Time-window errors
  • 400resourceGroupName requires subscriptionId to be specified
  • 500Failed to retrieve resource graph changes summary: <message>

Response: { compactSummaries[], availableFilters, totalCount }. availableFilters is { changeTypes[], operationTypes[] (same values), users[] }. Each summary:

resource-changes-summary summary fields
FieldMeaning
entityId, displayName, entityTypeARM ID (Azure casing), name, level
subscriptionId, subscriptionName, resourceGroupName?, resourceType?, managementGroupId?, managementGroupName?Location
totalCountChanges
changeTypeCounts{ Create, Update, Delete }
userCountsKeyed by display name, else changer ID, else "Unknown"
combinedCountsKey changeType|user; split on the first |

Example

GET /api/resource-changes-summary?start=…&end=…&subscriptionId=<guid>

GET /api/getChangeAttribution

Permission: View Resource Changes and/or View Azure Activity Logs. Each source is used when you have its permission

For a window, who changed each resource.

Parameters

getChangeAttribution parameters
NameRequiredNotes
startTimestamp, endTimestampyesTime window. Bounds are compared as you sent them, not whole-second normalised
subscriptionIdsnoEncoded list, max 200. Management-group records are always included

Errors

  • 403Requires change_tracking.read or activity_log.read permission
  • 400Please provide both startTimestamp and endTimestamp query parameters
  • 400Time-window and list errors
  • 500Failed to retrieve change attribution

Response: { attributions, sources, timeWindow }.

getChangeAttribution response fields
FieldMeaning
attributionsObject keyed by lower-case resource ID. Each value is an array of { key, displayName, sources: ["arg" | "activity"], changeCount, rbacCount, lastChangeTime }
sources{ arg, activity }: which sources were used
timeWindowEchoes your input

Example

GET /api/getChangeAttribution?startTimestamp=2026-10-07T02:00:00Z&endTimestamp=2026-10-14T02:00:00Z&subscriptionIds=<guid1>,<guid2>

Azure Activity Log

GET /api/getActivityLogsInTimeWindow

Permission: View Azure Activity Logs

Activity Log operations that changed something, in a window. Ordered oldest first, no paging.

Parameters

getActivityLogsInTimeWindow parameters
NameRequiredNotes
startTimestamp, endTimestampyesTime window
resourceIdsnoCSV, max 200. A prefix match, so child resources are included. Send lower-case IDs
subscriptionIdsnoCSV, max 200
includeFailedOperationsnoDefault true; only false turns it off

Errors

  • 400Please provide both startTimestamp and endTimestamp query parameters
  • 400Time-window errors
  • 400resourceIds must list at least one resource ID
  • 400resourceIds must list at most 200 values
  • 400subscriptionIds must list at least one subscription ID
  • 400subscriptionIds must list at most 200 values
  • 500Failed to retrieve activity logs in time window

Response: { operations[], timeWindow, totalCount, includeFailedOperations, resourceIds, subscriptionIds }. Each operation:

Activity Log operation fields
FieldMeaning
resourceId, originalResourceId?, resourceName?, resourceType, resourceGroupName, subscriptionId, subscriptionName?, managementGroupId?, managementGroupName?, entityType?Target
operationNameE.g. Microsoft.Compute/virtualMachines/write
operationTypecreate, update, delete, action, rbac
operationCategoryAdministrative, Security, Policy, ServiceHealth
statusStarted, Accepted, Succeeded, Failed, Active, Resolved, InProgress
caller, userDisplayName?, sourceIpAddress?Who
timestamp, correlationId, operationIdWhen and IDs
changeSummary?, keyChanges?[]keyChanges items: { field, friendlyName, oldValue?, newValue?, changeType: added | removed | modified }
requestBody?, responseBody?Raw JSON strings, may be truncated
roleAssignmentDetails?RBAC operations only
subscriptionMoveDetails?Subscription moves only

Example

GET /api/getActivityLogsInTimeWindow?startTimestamp=…&endTimestamp=…&subscriptionIds=<guid>&includeFailedOperations=false

GET /api/activity-log-summary

Permission: View Azure Activity Logs

Operation counts per entity for a window. Counts all operations, not only changes.

Parameters

activity-log-summary parameters
NameRequiredNotes
startTimestamp, endTimestampyesTime window

Errors

  • 400Please provide both startTimestamp and endTimestamp query parameters
  • 400Time-window errors
  • 500Failed to retrieve activity log hierarchy summary

Response: { compactSummaries[], availableFilters: { operationTypes[], users[] }, totalCount }. Each summary:

activity-log-summary summary fields
FieldMeaning
entityId, displayName, entityTypeThe entity
subscriptionId, subscriptionName, managementGroupId?, managementGroupName?, resourceGroupName?, resourceType?Location
totalCountOperations
operationTypeCountsPer operation type
userCountsOperations without a known user are not counted here
combinedCountsKey operationType|user; either part may be missing

Example

GET /api/activity-log-summary?startTimestamp=…&endTimestamp=…

GET /api/activity-log-details

Permission: View Azure Activity Logs

All operations on one entity in a window. Only operations recorded at that exact level are returned, and all operations are included, not only changes.

Parameters

activity-log-details parameters
NameRequiredNotes
startTimestamp, endTimestampyesTime window
entityTypeyessubscription, resourceGroup, resource, managementGroup
Identifiersper entityTypeFor management groups, managementGroupId is the full path /providers/Microsoft.Management/managementGroups/<id>, URL-encoded

Errors

  • 400Time-window errors
  • 400entityType is required
  • 400entityType must be one of subscription, resourceGroup, resource, managementGroup
  • 400subscriptionId is required for non-managementGroup entityTypes
  • 400managementGroupId is required for managementGroup entityType
  • 400resourceGroupName is required for resourceGroup entityType
  • 400resourceName and resourceGroupName are required for resource entityType
  • 500Failed to retrieve activity log details

Response: { operations[], totalCount }, with the same operation fields as getActivityLogsInTimeWindow.

Notes

  • Unordered: sort by timestamp yourself.

Example

GET /api/activity-log-details?startTimestamp=…&endTimestamp=…&entityType=resource&subscriptionId=<guid>&resourceGroupName=rg-web&resourceName=app-web01

Was this page helpful?