メインコンテンツへスキップ

get-customer-notification

dci get-customer-notification

Returns one organization-wide cost-anomaly notification config. Requires the settings (Manage settings) permission. The API does not offer the Console's read-only Organization list; a caller without this permission receives 403. An id that is not a cost-anomaly config for this tenant returns 404, without saying whether it exists elsewhere.

Output​

OK - Organization notification returned.

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

FieldTypeDescription
idstringServer-assigned notification id. null only on a dry-run create.
namestringDisplay name of the notification (max 200 characters). The stored name is trimmed.
createTimestring (date-time)When the config was created. null only on a dry-run create.
updateTimestring (date-time)When the config was last changed. null only on a dry-run create.
etagstringCurrent strong ETag as bare SHA-256 hex. The ETag response header and If-Match wrap this value in double quotes. Send that quoted form unchanged on update or delete. null only on a dry-run create.
destinationsobjectDelivery targets. Always includes emails, slackChannels, and teamsChannels. Unused lists are empty arrays.
destinations.emailsarray of string (email)Email addresses that receive the notification, in the order sent. The array is required; an empty array means email is unused. Omitting the array is rejected. At least one of emails, slackChannels, or teamsChannels must be non-empty. Addresses are stored and returned lowercase. A duplicate or an invalid email is 422.
destinations.slackChannelsarray of stringSlack channel ids for Slack channels that receive the notification, in the order sent. The array is required; an empty array means Slack is unused. Omitting the array is rejected. At least one of emails, slackChannels, or teamsChannels must be non-empty. Accepts a public channel, a shared channel, or a private channel the caller is a member of when the DoiT app is also in that channel. A service account cannot add a private channel and receives the same 422 as an id outside the tenant. The caller supplies the id; this API does not look channels up. A duplicate or an id outside the tenant is 422 without saying whether it exists elsewhere. After a channel is accepted, get and list keep returning that id even if the channel is later deleted, archived, or disconnected. That does not mean delivery still works.
destinations.teamsChannelsarray of stringMicrosoft Teams conversation ids for Microsoft Teams channels that receive the notification, in the order sent. The array is required; an empty array means Teams is unused. Omitting the array is rejected. At least one of emails, slackChannels, or teamsChannels must be non-empty. A duplicate or an id outside the tenant is 422 without saying whether it exists elsewhere. A Teams id is also 422 when the tenant has no Teams entitlement. After a channel is accepted, get and list keep returning that id even if the channel is later deleted, archived, or disconnected, or the tenant loses Teams entitlement. That does not mean delivery still works.
settingsobjectSubscribed notification settings. Only costAnomalies is accepted; any other notification type is rejected.
settings.costAnomaliesobjectCost-anomaly notification settings: minimum severity, excess-cost threshold, allocation scope, and optional resend controls.
settings.costAnomalies.minSeveritystringwarning — warning and above. critical — critical only. There is no information or all value; a write of all is rejected with 422. Clients may send only warning or critical. Responses return only warning or critical. A missing or empty stored severity (console "All severity levels") is returned as warning. critical is stored and returned as critical. One of: "warning", "critical".
settings.costAnomalies.minExcessCostobjectMinimum excess cost, as Money. Notify when excess cost is above this amount, not total spend. 100.00 USD means $100. currency must be USD; any other currency is rejected with 422. A negative amount is rejected with 422. A fractional amount is rejected with 422 (100.99 is not a whole number of dollars). 100 and 100.00 are both accepted. 0 and 0.00 are accepted. Amounts above 1,000,000,000 whole dollars, and forms such as Inf, exponents, a leading +, or underscores, are rejected with 422. Responses return the amount as "100.00".
settings.costAnomalies.minExcessCost.amountstringDecimal monetary amount at ISO 4217 minor-unit precision (string).
settings.costAnomalies.minExcessCost.currencystringISO 4217 currency code.
settings.costAnomalies.allocationsobjectAllocation scope for cost-anomaly notifications. ids are allocation ids from GET /analytics/v1/allocations. An id outside the caller's tenant is rejected with 422 without saying whether it exists elsewhere. mode: all means every allocation with anomaly detection enabled, including anomalies that are not tied to an allocation, and it carries an empty ids. include and exclude require at least one id. mode: all with a non-empty ids, and include or exclude with an empty ids, are rejected with 422. ids are an ordered list: the server stores and returns them in the order sent, and it does not sort or drop entries. A duplicate id is rejected with 422.
settings.costAnomalies.allocations.modestringall — every allocation with anomaly detection enabled (and unallocated anomalies). include — only the listed ids. exclude — all enabled allocations except the listed ids. all cannot be sent with a non-empty ids. include and exclude cannot be sent with an empty ids. One of: "all", "include", "exclude".
settings.costAnomalies.allocations.idsarray of stringAllocation ids, in the order sent. A read returns that same order. A duplicate id is rejected with 422. Empty when mode is all. Non-empty when mode is include or exclude.
settings.costAnomalies.repeatobjectResend controls for an active cost anomaly. Omit the whole repeat object when neither control is set. An empty object is rejected with 422.
settings.costAnomalies.repeat.everyHoursintegerResend until the anomaly is inactive, every N hours (1–24).
settings.costAnomalies.repeat.whenCostGrowsobjectResend when the anomaly's cost grows. At least one of percentIncrease or minIncrease is required. An object with only withinHours, only match, or neither amount is rejected with 422. - both percentIncrease and minIncrease present → match is required (or or and) - exactly one of percentIncrease or minIncrease present → omit match (percentage-only or value-only) - neither amount present → rejected with 422 percentIncrease is an integer percent (10 means 10 percent) and must be at least 1. Omit withinHours when the time window is off. Nested fields omitted — see the raw JSON schema.

Example response (--output json)​

{
"id": "notif_01HX9P2KQVJ8Z3M4T5N6V7W8Y9",
"name": "Anomaly alerts",
"createTime": "2026-10-01T08:00:00Z",
"updateTime": "2026-10-01T08:00:00Z",
"etag": "3f7a1c9e2b4d6f8a0c1e3a5b7d9f1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a3c5e",
"destinations": {
"emails": [
],
"slackChannels": [
"C0123ABCD"
],
"teamsChannels": []
},
"settings": {
"costAnomalies": {
"minSeverity": "warning",
"minExcessCost": {
"amount": "100.00",
"currency": "USD"
},
"allocations": {
"mode": "include",
"ids": [
"alloc_abc",
"alloc_def"
]
}
}
}
}
Raw JSON schema
{
"type": "object",
"additionalProperties": false,
"description": "Organization-wide notification config. Create and read return the full\nresource with the same field names. Update and delete require\n`If-Match` against the strong `etag`.\n",
"required": [
"id",
"name",
"createTime",
"updateTime",
"etag",
"destinations",
"settings"
],
"properties": {
"id": {
"type": "string",
"readOnly": true,
"x-terraform-computed": true,
"description": "Server-assigned notification id. `null` only on a dry-run create.",
"nullable": true,
"example": "notif_01HX9P2KQVJ8Z3M4T5N6V7W8Y9"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Display name of the notification (max 200 characters). The stored name is trimmed.",
"example": "Anomaly alerts"
},
"createTime": {
"type": "string",
"format": "date-time",
"readOnly": true,
"x-terraform-computed": true,
"description": "When the config was created. `null` only on a dry-run create.",
"nullable": true,
"example": "2026-10-01T08:00:00Z"
},
"updateTime": {
"type": "string",
"format": "date-time",
"readOnly": true,
"x-terraform-computed": true,
"description": "When the config was last changed. `null` only on a dry-run create.",
"nullable": true,
"example": "2026-10-01T08:00:00Z"
},
"etag": {
"type": "string",
"readOnly": true,
"x-terraform-computed": true,
"description": "Current strong ETag as bare SHA-256 hex. The `ETag` response header\nand `If-Match` wrap this value in double quotes. Send that quoted\nform unchanged on update or delete. `null` only on a dry-run create.\n",
"nullable": true,
"example": "3f7a1c9e2b4d6f8a0c1e3a5b7d9f1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a3c5e"
},
"destinations": {
"description": "Delivery targets. Always includes `emails`, `slackChannels`, and\n`teamsChannels`. Unused lists are empty arrays.\n",
"allOf": [
{
"type": "object",
"additionalProperties": false,
"description": "Delivery targets for an organization notification. All three arrays are always present on read. An unused destination is an empty array, never omitted and never `null`. On create, and on a patch that includes `destinations`, all three arrays are required and at least one must be non-empty. An object whose three arrays are all empty is rejected with `422`. Each array is kept in the order sent; a later read returns that same order. Emails are trimmed and stored lowercase. Channel ids are trimmed and otherwise unchanged. A duplicate value inside one array is rejected with `422` (emails compared after lowercase; channel ids compared exactly after trim).",
"required": [
"emails",
"slackChannels",
"teamsChannels"
],
"properties": {
"emails": {
"type": "array",
"minItems": 0,
"description": "Email addresses that receive the notification, in the order sent. The array is required; an empty array means email is unused. Omitting the array is rejected. At least one of `emails`, `slackChannels`, or `teamsChannels` must be non-empty. Addresses are stored and returned lowercase. A duplicate or an invalid email is `422`.",
"items": {
"type": "string",
"format": "email",
"minLength": 1,
"x-doit-pii": true
},
"example": [
]
},
"slackChannels": {
"type": "array",
"minItems": 0,
"description": "Slack channel ids for Slack channels that receive the notification, in the order sent. The array is required; an empty array means Slack is unused. Omitting the array is rejected. At least one of `emails`, `slackChannels`, or `teamsChannels` must be non-empty. Accepts a public channel, a shared channel, or a private channel the caller is a member of when the DoiT app is also in that channel. A service account cannot add a private channel and receives the same `422` as an id outside the tenant. The caller supplies the id; this API does not look channels up. A duplicate or an id outside the tenant is `422` without saying whether it exists elsewhere. After a channel is accepted, get and list keep returning that id even if the channel is later deleted, archived, or disconnected. That does not mean delivery still works.",
"items": {
"type": "string",
"minLength": 1
},
"example": [
"C0123ABCD"
]
},
"teamsChannels": {
"type": "array",
"minItems": 0,
"description": "Microsoft Teams conversation ids for Microsoft Teams channels that receive the notification, in the order sent. The array is required; an empty array means Teams is unused. Omitting the array is rejected. At least one of `emails`, `slackChannels`, or `teamsChannels` must be non-empty. A duplicate or an id outside the tenant is `422` without saying whether it exists elsewhere. A Teams id is also `422` when the tenant has no Teams entitlement. After a channel is accepted, get and list keep returning that id even if the channel is later deleted, archived, or disconnected, or the tenant loses Teams entitlement. That does not mean delivery still works.",
"items": {
"type": "string",
"minLength": 1
},
"example": [
]
}
}
}
]
},
"settings": {
"description": "Subscribed notification settings. Only `costAnomalies` is accepted; any other notification type is rejected.",
"allOf": [
{
"type": "object",
"additionalProperties": false,
"description": "Subscribed notification settings. Only `costAnomalies` is accepted.\nSettings for any other type are rejected; omitting `costAnomalies` is\nrejected.\n",
"required": [
"costAnomalies"
],
"properties": {
"costAnomalies": {
"type": "object",
"additionalProperties": false,
"description": "Cost-anomaly notification settings: minimum severity, excess-cost threshold, allocation scope, and\noptional resend controls.\n",
"required": [
"minSeverity",
"minExcessCost",
"allocations"
],
"properties": {
"minSeverity": {
"type": "string",
"enum": [
"warning",
"critical"
],
"x-enumDescriptions": {
"warning": "Warning and above. A missing stored severity (Console \"All severity levels\") is also returned as `warning`.",
"critical": "Critical."
},
"description": "`warning` — warning and above. `critical` — critical only. There is no `information` or `all` value; a write of `all` is rejected with `422`. Clients may send only `warning` or `critical`. Responses return only `warning` or `critical`. A missing or empty stored severity (console \"All severity levels\") is returned as `warning`. `critical` is stored and returned as `critical`.",
"example": "warning"
},
"minExcessCost": {
"description": "Minimum excess cost, as Money. Notify when excess cost is above this amount, not total spend.\n`100.00` USD means $100. `currency` must be `USD`; any other currency is rejected with `422`. A\nnegative amount is rejected with `422`. A fractional amount is rejected with `422` (`100.99` is not a\nwhole number of dollars). `100` and `100.00` are both accepted. `0` and `0.00` are accepted. Amounts\nabove 1,000,000,000 whole dollars, and forms such as `Inf`, exponents, a leading `+`, or underscores,\nare rejected with `422`. Responses return the amount as `\"100.00\"`.\n",
"allOf": [
{
"type": "object",
"required": [
"amount",
"currency"
],
"properties": {
"amount": {
"type": "string",
"pattern": "^-?(0|[1-9]\\d*)(\\.\\d+)?$",
"description": "Decimal monetary amount at ISO 4217 minor-unit precision (string).",
"example": "100.00"
},
"currency": {
"type": "string",
"pattern": "^[A-Z]{3}$",
"description": "ISO 4217 currency code.",
"example": "USD"
}
}
}
]
},
"allocations": {
"type": "object",
"additionalProperties": false,
"description": "Allocation scope for cost-anomaly notifications. `ids` are allocation ids from `GET\n/analytics/v1/allocations`. An id outside the caller's tenant is rejected with `422` without saying\nwhether it exists elsewhere.\n\n`mode: all` means every allocation with anomaly detection enabled, including anomalies that are not\ntied to an allocation, and it carries an empty `ids`. `include` and `exclude` require at least one\nid. `mode: all` with a non-empty `ids`, and `include` or `exclude` with an empty `ids`, are rejected\nwith `422`. `ids` are an ordered list: the server stores and returns them in the order sent, and it does\nnot sort or drop entries. A duplicate id is rejected with `422`.\n",
"required": [
"mode",
"ids"
],
"properties": {
"mode": {
"type": "string",
"enum": [
"all",
"include",
"exclude"
],
"x-enumDescriptions": {
"all": "Include all enabled allocations, including anomalies that are not tied to an allocation. Send an empty `ids`.",
"include": "Include specific allocations. Requires at least one id.",
"exclude": "Exclude specific allocations. Requires at least one id."
},
"description": "`all` — every allocation with anomaly detection enabled (and unallocated anomalies). `include` — only the listed ids. `exclude` — all enabled allocations except the listed ids. `all` cannot be sent with a non-empty `ids`. `include` and `exclude` cannot be sent with an empty `ids`.",
"example": "include"
},
"ids": {
"type": "array",
"description": "Allocation ids, in the order sent. A read returns that same order. A duplicate id is rejected\nwith `422`. Empty when `mode` is `all`. Non-empty when `mode` is `include` or `exclude`.\n",
"items": {
"type": "string",
"minLength": 1
},
"example": [
"alloc_abc",
"alloc_def"
]
}
}
},
"repeat": {
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"description": "Resend controls for an active cost anomaly. Omit the whole `repeat` object when neither control is\nset. An empty object is rejected with `422`.\n",
"properties": {
"everyHours": {
"type": "integer",
"minimum": 1,
"maximum": 24,
"description": "Resend until the anomaly is inactive, every N hours (1–24).\n",
"example": 24
},
"whenCostGrows": {
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"description": "Resend when the anomaly's cost grows. At least one of `percentIncrease` or `minIncrease` is required.\nAn object with only `withinHours`, only `match`, or neither amount is rejected with `422`.\n\n- both `percentIncrease` and `minIncrease` present → `match` is\n required (`or` or `and`)\n- exactly one of `percentIncrease` or `minIncrease` present → omit\n `match` (percentage-only or value-only)\n- neither amount present → rejected with `422`\n\n`percentIncrease` is an integer percent (`10` means 10 percent) and must be at least 1. Omit\n`withinHours` when the time window is off.",
"properties": {
"match": {
"type": "string",
"enum": [
"or",
"and"
],
"x-enumDescriptions": {
"or": "Resend when either the percent increase or the dollar increase is reached.",
"and": "Resend only when both are reached."
},
"description": "How to combine percent and dollar growth when both are set. Required when both amounts are present; omit when only one amount is present.",
"example": "or"
},
"percentIncrease": {
"type": "integer",
"minimum": 1,
"description": "Minimum percent cost increase that triggers a resend. `10` means 10 percent. Must be greater than 0.\n",
"example": 10
},
"minIncrease": {
"description": "Minimum cost growth that triggers a resend, as Money. Must be a positive whole number of dollars.\n`150.00` USD means $150. `currency` must be `USD`; any other currency is rejected with `422`. `0`,\n`0.00`, and a negative amount are rejected with `422`. A fractional amount is rejected with `422`\n(`150.99` is not a whole number of dollars). `150` and `150.00` are both accepted. Amounts above\n1,000,000,000 whole dollars, and forms such as `Inf`, exponents, a leading `+`, or underscores, are\nrejected with `422`. Responses return the amount as `\"150.00\"`.\n",
"allOf": [
{
"type": "object",
"required": [
"amount",
"currency"
],
"properties": {
"amount": {
"type": "string",
"pattern": "^-?(0|[1-9]\\d*)(\\.\\d+)?$",
"description": "Decimal monetary amount at ISO 4217 minor-unit precision (string).",
"example": "100.00"
},
"currency": {
"type": "string",
"pattern": "^[A-Z]{3}$",
"description": "ISO 4217 currency code.",
"example": "USD"
}
}
}
]
},
"withinHours": {
"type": "integer",
"minimum": 1,
"maximum": 24,
"description": "Optional window in hours for the growth check (1–24).",
"example": 6
}
}
}
}
}
}
}
}
}
]
}
}
}

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 status to exit code mapping
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.
50040API_SERVER_ERRORThe API failed to process the request. Retryable; contact DoiT support if it persists.

Aliases: getcustomernotification