Skip to main content

list-anomalies

dci list-anomalies [flags]

Returns a list of detected anomalies. Anomalies can be sorted by startTime, severityLevel, or costOfAnomaly using sortBy and sortOrder. By default they are sorted by startTime in descending order (most recent first). The sort order is total and reproducible: ties on the selected field are broken by startTime descending and then by anomaly id ascending, so the same result set always paginates in the same order. The notifications array is always present on each anomaly item; it is empty unless includeNotifications=true is supplied. Pagination stability: sortBy, sortOrder, filter, minCreationTime, and maxCreationTime must be held constant across a pagination sequence. A pageToken presented with any of them changed is rejected with 400.

CLI default view

dci list-anomalies presents a curated table by default:

  • Columns: service (from serviceName), severity (from severityLevel), anomaly cost (from costOfAnomaly), platform, status, and started (UTC) (from startTime).
  • started (UTC) always stays in UTC, regardless of timezone settings: it labels the anomaly's usage window (a UTC billing bucket), so a local-time rendering would relabel which day was anomalous — see Timestamps and timezones.
  • The server's sort order is kept — control it with --sort-by and --sort-order.
  • --output json and explicit -C/--fields selections return the raw fields documented below.

Flags

--min-creation-time: (integer format:int64)

--max-creation-time: (integer format:int64)

--filter: (string)

--sort-by: (string default:"startTime" enum:"startTime","severityLevel","costOfAnomaly")

--sort-order: (string enum:"asc","desc")

--max-results: (integer format:int64)

--page-token: (string)

--include-notifications: (boolean default:false)

Output

OK - The request succeeded.

By default dci renders the result as a table. Use --output json to get the full structure described below — see Output formats.

FieldTypeDescription
anomaliesarray of objectAnomalies in this page. Always an array; empty ([]) when there are no matching anomalies.
anomalies[].attributionstringAttribution ID.
anomalies[].billingAccountstringBilling account ID.
anomalies[].costOfAnomalynumber (double)Excess cost over and above the expected normal cost.
anomalies[].actualCostnumber (double)Observed (actual) cost of the anomaly.
anomalies[].expectedMaxCostnumber (double)Maximum cost within the expected normal range.
anomalies[].idstring
anomalies[].platformstringCloud Provider name.
anomalies[].scopestringScope: Project or Account
anomalies[].serviceNamestringService name.
anomalies[].severityLevelstringSeverity level: information, warning, or critical.
anomalies[].startTimeinteger (int64)Usage start time of the anomaly.
anomalies[].endTimeintegerEnd of the anomaly.
anomalies[].deactivationReasonstringWhy the anomaly stopped being active. reverted means the cost returned inside the expected normal range; expired means the anomaly was deactivated without the cost returning inside that range; unknown means the reason could not be determined. Null while the anomaly is still active. One of: "reverted", "expired", "unknown".
anomalies[].timeFramestringTimeframe: Daily or Hourly
anomalies[].top3SKUsarray of objectArray of SKU entries contributing to an anomaly.
anomalies[].top3SKUs[].costnumber (double)
anomalies[].top3SKUs[].namestring
anomalies[].resourceDataarray of objectArray of resources contributing to an anomaly.
anomalies[].resourceData[].costnumber (double)
anomalies[].resourceData[].resourceIdstring
anomalies[].resourceData[].skuDescriptionstring
anomalies[].resourceData[].operationstringFor anomalies related to AWS S3
anomalies[].resourceData[].labelsarray of objectLabels (also known as cost-allocation tags) present on this resource during the anomaly; each entry reports the label's key, its value, and the resource's cost tagged with that key/value pair. Cloud providers use different names for the same concept; GCP uses "labels", AWS uses "cost-allocation tags", and Azure uses "tags". We refer to all of these as labels.
anomalies[].resourceData[].labels[].keystringThe label/tag key.
anomalies[].resourceData[].labels[].valuestringThe label/tag value.
anomalies[].resourceData[].labels[].costnumber (double)The resource's cost tagged with this key/value pair; typically equal to the resource's cost, since labels/tags usually cover all of its spend.
anomalies[].statusstringOne of: "active", "inactive".
anomalies[].acknowledgedbooleanHas the anomaly been acknowledged
anomalies[].acknowledgedAtstring (date-time)When the anomaly was first acknowledged
anomalies[].acknowledgedBystringEmail of the user who first acknowledged the anomaly
anomalies[].notificationsarray of objectChronologically ordered notification dispatch events.
anomalies[].notifications[].timestampstring (date-time)Dispatch timestamp in RFC3339 UTC.
anomalies[].notifications[].channelstringDispatch channel. One of: "email", "slack", "msteams".
pageTokenstringOpaque token for the next page. Omitted when there is no next page.
rowCountinteger (int64)Number of items in this page (anomalies.length). This is not the total count across all pages; the total across the full filtered result set is totalCount.
truncatedbooleantrue when filtered anomalies remain beyond this page. Derived from the same "rows remain after the last returned row" check as pageToken, so the two are never contradictory: pageToken is present if and only if truncated is true.
totalCountinteger (int64)Total number of anomalies matching the filters and time window, across all pages. This is a per-request snapshot: under concurrent writes, the value can differ between pages fetched during the same pagination sequence.
totalCountExactbooleanWhether totalCount is exact. Always true for this operation, because totalCount is computed over the fully materialised filtered result set.
anomalySummaryobjectAnomaly-specific summary. countBySeverity and totalCostOfAnomaly cover the complete filtered result set across all pages, not the returned page. Anomalies whose severity cannot be determined (legacy documents) are counted in totalCount and totalCostOfAnomaly but in none of the three severity buckets in countBySeverity, so the three values can sum to less than totalCount. Computed as of this request; under concurrent writes, values may differ between pages fetched during the same pagination sequence.
anomalySummary.countBySeverityobjectCount of matching anomalies per severity level. All three keys are always present, with zero counts included.
anomalySummary.countBySeverity.informationinteger (int64)
anomalySummary.countBySeverity.warninginteger (int64)
anomalySummary.countBySeverity.criticalinteger (int64)
anomalySummary.totalCostOfAnomalynumber (double)Sum of costOfAnomaly across all matching anomalies, in USD, rounded to cents.
Raw JSON schema
{
"type": "object",
"description": "List of detected cloud cost anomalies.",
"required": [
"anomalies",
"rowCount",
"truncated",
"totalCount",
"totalCountExact",
"anomalySummary"
],
"properties": {
"anomalies": {
"type": "array",
"description": "Anomalies in this page. Always an array; empty (`[]`) when there are no matching anomalies.",
"items": {
"required": [
"attribution",
"billingAccount",
"costOfAnomaly",
"platform",
"scope",
"serviceName",
"severityLevel",
"startTime",
"timeFrame",
"top3SKUs",
"notifications"
],
"type": "object",
"description": "Detailed information about a detected anomaly. The `notifications` array is always present; list responses return an empty array unless `includeNotifications=true` is requested.",
"properties": {
"attribution": {
"type": "string",
"description": "Attribution ID."
},
"billingAccount": {
"type": "string",
"description": "Billing account ID."
},
"costOfAnomaly": {
"type": "number",
"description": "Excess cost over and above the expected normal cost.",
"format": "double"
},
"actualCost": {
"type": "number",
"format": "double",
"nullable": true,
"description": "Observed (actual) cost of the anomaly."
},
"expectedMaxCost": {
"type": "number",
"format": "double",
"nullable": true,
"description": "Maximum cost within the expected normal range."
},
"id": {
"type": "string"
},
"platform": {
"type": "string",
"description": "Cloud Provider name."
},
"scope": {
"type": "string",
"description": "Scope: Project or Account"
},
"serviceName": {
"type": "string",
"description": "Service name."
},
"severityLevel": {
"type": "string",
"description": "Severity level: `information`, `warning`, or `critical`."
},
"startTime": {
"type": "integer",
"description": "Usage start time of the anomaly.",
"format": "int64"
},
"endTime": {
"type": "integer",
"nullable": true,
"description": "End of the anomaly."
},
"deactivationReason": {
"type": "string",
"nullable": true,
"description": "Why the anomaly stopped being active. `reverted` means the cost returned inside the expected normal range; `expired` means the anomaly was deactivated without the cost returning inside that range; `unknown` means the reason could not be determined. Null while the anomaly is still active.",
"enum": [
"reverted",
"expired",
"unknown"
]
},
"timeFrame": {
"type": "string",
"description": "Timeframe: Daily or Hourly"
},
"top3SKUs": {
"type": "array",
"description": "Array of SKU entries contributing to an anomaly.",
"items": {
"type": "object",
"description": "SKU-level information contributing to an anomaly.",
"properties": {
"cost": {
"type": "number",
"format": "double"
},
"name": {
"type": "string"
}
}
}
},
"resourceData": {
"type": "array",
"description": "Array of resources contributing to an anomaly.",
"items": {
"type": "object",
"description": "Resource-specific contribution to an anomaly.",
"properties": {
"cost": {
"type": "number",
"format": "double"
},
"resourceId": {
"type": "string"
},
"skuDescription": {
"type": "string"
},
"operation": {
"description": "For anomalies related to AWS S3",
"type": "string"
},
"labels": {
"type": "array",
"description": "Labels (also known as cost-allocation tags) present on this resource during the anomaly; each entry reports the label's key, its value, and the resource's cost tagged with that key/value pair.\nCloud providers use different names for the same concept; GCP uses \"labels\", AWS uses \"cost-allocation tags\", and Azure uses \"tags\". We refer to all of these as labels.",
"items": {
"type": "object",
"description": "A single label (a.k.a. cost-allocation tag) on the resource, paired with the resource's cost tagged with this key/value pair.",
"properties": {
"key": {
"type": "string",
"description": "The label/tag key."
},
"value": {
"type": "string",
"description": "The label/tag value."
},
"cost": {
"type": "number",
"format": "double",
"description": "The resource's cost tagged with this key/value pair; typically equal to the resource's cost, since labels/tags usually cover all of its spend."
}
}
}
}
}
}
},
"status": {
"type": "string",
"nullable": true,
"enum": [
"active",
"inactive"
]
},
"acknowledged": {
"description": "Has the anomaly been acknowledged",
"type": "boolean"
},
"acknowledgedAt": {
"description": "When the anomaly was first acknowledged",
"type": "string",
"format": "date-time",
"nullable": true
},
"acknowledgedBy": {
"description": "Email of the user who first acknowledged the anomaly",
"type": "string",
"nullable": true
},
"notifications": {
"type": "array",
"description": "Chronologically ordered notification dispatch events.",
"items": {
"type": "object",
"description": "A successful notification dispatch for an anomaly.\nThis records that the API/worker sent the notification, not that delivery was confirmed.",
"required": [
"timestamp",
"channel"
],
"properties": {
"timestamp": {
"type": "string",
"format": "date-time",
"description": "Dispatch timestamp in RFC3339 UTC."
},
"channel": {
"type": "string",
"description": "Dispatch channel.",
"enum": [
"email",
"slack",
"msteams"
]
}
}
}
}
}
}
},
"pageToken": {
"type": "string",
"description": "Opaque token for the next page. Omitted when there is no next page."
},
"rowCount": {
"type": "integer",
"format": "int64",
"description": "Number of items in this page (`anomalies.length`). This is not the total count across all pages; the total across the full filtered result set is `totalCount`."
},
"truncated": {
"type": "boolean",
"description": "`true` when filtered anomalies remain beyond this page. Derived from the same \"rows remain after the last returned row\" check as `pageToken`, so the two are never contradictory: `pageToken` is present if and only if `truncated` is `true`."
},
"totalCount": {
"type": "integer",
"format": "int64",
"description": "Total number of anomalies matching the filters and time window, across all pages. This is a per-request snapshot: under concurrent writes, the value can differ between pages fetched during the same pagination sequence."
},
"totalCountExact": {
"type": "boolean",
"description": "Whether `totalCount` is exact. Always `true` for this operation, because `totalCount` is computed over the fully materialised filtered result set."
},
"anomalySummary": {
"type": "object",
"description": "Anomaly-specific summary. `countBySeverity` and `totalCostOfAnomaly` cover the complete filtered result set across all pages, not the returned page. Anomalies whose severity cannot be determined (legacy documents) are counted in `totalCount` and `totalCostOfAnomaly` but in none of the three severity buckets in `countBySeverity`, so the three values can sum to less than `totalCount`. Computed as of this request; under concurrent writes, values may differ between pages fetched during the same pagination sequence.",
"required": [
"countBySeverity",
"totalCostOfAnomaly"
],
"properties": {
"countBySeverity": {
"type": "object",
"description": "Count of matching anomalies per severity level. All three keys are always present, with zero counts included.",
"required": [
"information",
"warning",
"critical"
],
"properties": {
"information": {
"type": "integer",
"format": "int64"
},
"warning": {
"type": "integer",
"format": "int64"
},
"critical": {
"type": "integer",
"format": "int64"
}
}
},
"totalCostOfAnomaly": {
"type": "number",
"format": "double",
"description": "Sum of `costOfAnomaly` across all matching anomalies, in USD, rounded to cents."
}
}
}
}
}

Errors

On failure, dci prints a single error message — with a hint when one is available — and exits with a typed code your scripts can branch on. See Errors and exit codes for the full contract.

HTTP statusExit codeError codeMeaning
40030VALIDATION_ERRORThe arguments or request body were rejected. Review the command's flags and payload.
40110AUTHENTICATION_FAILEDNot signed in, or the API token is invalid. Run dci login or check DCI_API_KEY.
40311PERMISSION_DENIEDThe DoiT user or the active customer context does not have access.
40420RESOURCE_NOT_FOUNDThe requested resource does not exist. Check the identifier argument.

Aliases: listanomalies