Reference: Azure Policy
Policy compliance and assignments per scan, and how they changed. This is the data behind the Policy & Governance pages. Every route here needs View Policy Data. The four single-scan routes accept scanId=latest; the two diff routes take a scan pair and return 404 for latest.
6 Routes
Shared behaviour
- Detail routes return items at exactly the requested level. Inherited assignments and child resources are not included.
- An out-of-scope subscription or management group returns an empty list.
complianceStateis one ofCompliant,NonCompliant,Exempt,Conflict,Unknown.stateWeight(higher = worse): NonCompliant 300, Compliant 200, Error 150, Conflict 100, Exempt 50, Unknown 10.
Compliance
GET /api/policy-compliance-hierarchy
Permission: View Policy Dataaccepts scanId=latest
Compliance evaluation counts per evaluated entity.
Parameters
| Name | Required |
|---|---|
scanId | yes |
Errors
- 400
scanId parameter is required - 500
Failed to retrieve policy compliance hierarchy
Response: { compactSummaries[], availableFilters, totalCount }. availableFilters is { complianceStates[], policyActions[], categories[], assignments[] }, where each assignment is { assignmentId, displayName, policyDefinitionDisplayName?, scope, scopeType, friendlyScopeName }. Each summary:
| Field | Meaning |
|---|---|
entityId, displayName, entityType | Lower-case ID, name, level |
subscriptionId, subscriptionName, resourceGroupName, resourceType? | Location |
totalCount | Evaluations, one per assignment × policy definition |
complianceStateCounts | Per state |
policyActionCounts | E.g. audit, deny, deployIfNotExists |
categoryCounts | Initiative category |
combinedCounts | Key state|action|category|assignmentId; empty parts are kept; the assignment ID is lower-case |
Example
GET /api/policy-compliance-hierarchy?scanId=latestGET /api/policy-compliance-details
Permission: View Policy Dataaccepts scanId=latest
Every compliance evaluation for one entity.
Parameters
| Name | Required | Notes |
|---|---|---|
scanId | yes | |
entityType | no | subscription (default), resourceGroup, resource |
| Identifiers | per entityType | subscriptionId, resourceGroupName, resourceName |
Errors
- 400
entityType must be one of subscription, resourceGroup, resource - 400
scanId parameter is required - 400
subscriptionId parameter is required for subscription queries - 400
subscriptionId and resourceGroupName parameters are required for resource group queries - 400
subscriptionId, resourceGroupName, and resourceName parameters are required for resource queries - 500
Failed to retrieve policy compliance details
Response: { items[], totalCount }, worst state first, then by name. Each item:
| Group | Fields |
|---|---|
| Resource | resourceId, originalResourceId, resourceType, resourceName, resourceLocation, subscriptionId, subscriptionName, resourceGroupName, entityType |
| Assignment | policyAssignmentId, policyAssignmentName, policyAssignmentDisplayName, policyAssignmentScope |
| Definition | policyDefinitionId, policyDefinitionName, policyDefinitionDisplayName, policyDefinitionReferenceId (inside an initiative) |
| Initiative | policySetDefinitionId, policySetDefinitionName, policySetDefinitionDisplayName, policySetDefinitionCategory |
| Result | complianceState, stateWeight, policyDefinitionAction, complianceReasonCode, policyDefinitionGroupNames[], managementGroupIds |
| Times | evaluatedAt (when Azure evaluated), firstScanTimestamp, lastScanTimestamp, collectedAt |
Example
GET /api/policy-compliance-details?scanId=latest&entityType=resource&subscriptionId=<guid>&resourceGroupName=rg-web&resourceName=webapp01GET /api/policy-compliance-diff
Permission: View Policy Data
Compliance changes between two scans. Evaluations are matched on resource + assignment + definition. added/deleted means present in one scan only; modified means the state, weight, action or reason code changed. Not paged.
Parameters
| Name | Required |
|---|---|
baseScanId, compareScanId | yes |
Errors
- 400Scan-pair errors
- 500
An error occurred while processing the policy compliance comparison.
Response: { items[], totalChanges, addedCount, modifiedCount, deletedCount, becameNonCompliantCount, becameCompliantCount }. Each item is a full evaluation plus changeStatus, previousComplianceState? (modified only) and changes[] of { property, before, after }.
Notes
- Transitions into Exempt, Conflict or Unknown count only in
modifiedCount.
Example
GET /api/policy-compliance-diff?baseScanId=…&compareScanId=…Assignments and Exemptions
GET /api/policy-assignment-hierarchy
Permission: View Policy Dataaccepts scanId=latest
Policy assignments and exemptions per scope.
Parameters
| Name | Required |
|---|---|
scanId | yes |
Errors
- 400
scanId parameter is required - 500
Failed to retrieve policy assignment hierarchy
Response: { compactSummaries[], availableFilters: { documentTypes[], policyTypes[], enforcementModes[] }, totalCount }. Each summary:
| Field | Meaning |
|---|---|
entityId, displayName | Scope path, and the last segment of it |
entityType | Equals scopeType: managementGroup, subscription, resourceGroup, resource |
managementGroupId?, managementGroupName?, subscriptionId?, subscriptionName?, resourceGroupName? | Location |
totalCount | Every assignment and exemption at the scope (equals the sum of documentTypeCounts) |
documentTypeCounts | PolicyAssignment, PolicyExemption |
policyTypeCounts | policy, initiative |
enforcementCounts | "true" / "false" |
combinedCounts | Key docType|policyType|isEnforced|expiration. Expiration is expired, within30, within60, within90, beyond90 or none, computed at request time; empty parts are kept |
Notes
availableFilters.enforcementModesholdsDefault/DoNotEnforce, not true/false.
Example
GET /api/policy-assignment-hierarchy?scanId=latestGET /api/policy-assignment-details
Permission: View Policy Dataaccepts scanId=latest
Assignments and exemptions made at one scope. Tell the two kinds apart by docType.
Parameters
| Name | Required | Notes |
|---|---|---|
scanId | yes | |
entityType | no | managementGroup, subscription (default), resourceGroup, resource |
managementGroupId | for management groups | Plain ID, not a path |
subscriptionId, resourceGroupName, resourceName | per entityType | For resource, the name match is a substring match: web also matches webapp01 |
Errors
- 400
entityType must be one of managementGroup, subscription, resourceGroup, resource - 400
managementGroupId parameter is required for management group queries - 400Subscription, resource group and resource messages as in policy-compliance-details
- 500
Failed to retrieve policy assignment details
Response: { items[], totalCount }, sorted by name.
Assignment fields
| Field | Meaning |
|---|---|
assignmentId, name, displayName, description | Identity |
scope, scopeType, managementGroupId, managementGroupName, subscriptionId, subscriptionName, resourceGroupName | Where it is assigned |
policyDefinitionId, policyDefinitionDisplayName, policyType | policyType is policy or initiative |
enforcementMode, isEnforced | Default or DoNotEnforce, and the boolean |
parameters, notScopes[], nonComplianceMessages[] | Configuration |
identity | { type, principalId?, tenantId? } or null |
assignedBy, createdBy, createdOn, updatedBy, updatedOn | Audit fields |
Exemption fields
| Field | Meaning |
|---|---|
exemptionId, name, displayName, description | Identity |
Scope fields, resourceId | Where it applies |
policyAssignmentId, policyAssignmentDisplayName, policyDefinitionReferenceIds[] | What it exempts |
exemptionCategory, expiresOn | Waiver or Mitigated, and the expiry |
isExpired, daysUntilExpiration | Both as of the scan |
| Audit fields | As for assignments |
Example
GET /api/policy-assignment-details?scanId=latest&entityType=managementGroup&managementGroupId=corp-rootGET /api/policy-assignment-diff
Permission: View Policy Data
Assignment and exemption changes between two scans.
Parameters
| Name | Required |
|---|---|
baseScanId, compareScanId | yes |
Errors
- 400Scan-pair errors
- 500
An error occurred while processing the policy assignment comparison.
Response: { items[], summary[], totalChanges, addedCount, modifiedCount, deletedCount }.
| Field | Meaning |
|---|---|
items[] | Each is a full assignment or exemption plus changeStatus and changes[]. Added and deleted items carry the whole object in changes |
| Compared fields (assignments) | displayName, description, enforcementMode, isEnforced, parameters, notScopes, nonComplianceMessages, identity |
| Compared fields (exemptions) | displayName, description, exemptionCategory, expiresOn, isExpired, policyDefinitionReferenceIds, policyAssignmentDisplayName |
summary[] | { entityId, entityType, managementGroupId?, managementGroupName?, subscriptionId?, subscriptionName?, resourceGroupName?, addedCount, modifiedCount, deletedCount, totalChanges }. Each change counts at every level it belongs to |
Example
GET /api/policy-assignment-diff?baseScanId=…&compareScanId=…