create-insight
dci create-insight <sourceID> <insightKey> [body]
Creates or updates a single insight for the given source and key. If an insight with the same key already exists for the source, it will be updated. Resource results are managed separately via the resource-results endpoint.
sourceID— Only insights created via the public API can be managed. Currently only "public-api" is supported.insightKey— The unique key identifying the insight.
Pass the request body as name: value arguments or pipe JSON on stdin — see Command structure.
Examples
# Create an insight with the required metadata (the same key again updates it in place).
dci create-insight public-api idle-ec2-instances key: idle-ec2-instances, title: "Idle EC2 instances", shortDescription: "Instances under 5% CPU for the last 14 days", cloudProvider: aws, categories: [FinOps]
# Create it with the long description, an easy-win rationale, and a report link, from a file.
dci create-insight public-api idle-ec2-instances < insight.json
# insight.json
{"key": "idle-ec2-instances", "title": "Idle EC2 instances",
"shortDescription": "Instances under 5% CPU for the last 14 days",
"detailedDescriptionMdx": "## Why this matters\nThese instances have been idle for two weeks...",
"easyWinDescription": "Stopping idle instances needs no code change.",
"reportUrl": "https://console.doit.com/customers/acme/analytics/reports/idle-ec2",
"cloudProvider": "aws", "categories": ["FinOps"]}
# Dismiss the insight by re-sending it with a status (this replaces the deprecated update-insight-status).
dci create-insight public-api idle-ec2-instances < dismiss.json
# dismiss.json
{"key": "idle-ec2-instances", "title": "Idle EC2 instances",
"shortDescription": "Instances under 5% CPU for the last 14 days",
"cloudProvider": "aws", "categories": ["FinOps"],
"status": "dismissed",
"dismissalDetails": {"reason": "not relevant", "comment": "Sandbox account, stopped nightly"}}
Request
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
key | string | yes | A unique key for this insight within the source. |
title | string | yes | The display title of the insight. |
shortDescription | string | yes | A brief summary of the insight. |
detailedDescriptionMdx | string | A detailed description of the insight in MDX format. | |
cloudProvider | string | yes | The cloud provider associated with the resource. |
categories | array of string | yes | One or more categories this insight belongs to. |
reportUrl | string | URL to an external report related to this insight. | |
cloudFlowTemplateId | string | ID of a CloudFlow template that can automate the remediation of this insight. | |
easyWinDescription | string | A description of why this insight is considered an easy win. | |
status | string | The display status of the insight. One of: "actionable", "acknowledged", "optimized", "dismissed", "in progress", "upgrade needed", "permissions needed". | |
dismissalDetails | object | Details for why an insight was dismissed. | |
dismissalDetails.reason | string | The reason for dismissal. One of: "not relevant", "not enough information", "not worth the effort", "inaccurate optimization opportunities". | |
dismissalDetails.comment | string | An optional free-text comment providing additional context. |
Raw JSON schema
{
"type": "object",
"description": "Request body for creating or updating a single insight's metadata. Resource results are managed separately via the resource-results endpoint.",
"required": [
"key",
"title",
"shortDescription",
"cloudProvider",
"categories"
],
"properties": {
"key": {
"type": "string",
"description": "A unique key for this insight within the source."
},
"title": {
"type": "string",
"description": "The display title of the insight."
},
"shortDescription": {
"type": "string",
"description": "A brief summary of the insight."
},
"detailedDescriptionMdx": {
"type": "string",
"description": "A detailed description of the insight in MDX format."
},
"cloudProvider": {
"type": "string",
"example": "aws",
"description": "The cloud provider associated with the resource."
},
"categories": {
"description": "One or more categories this insight belongs to.",
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"description": "Allowed categories when creating insights via the public API.",
"enum": [
"FinOps",
"Security"
]
}
},
"reportUrl": {
"type": "string",
"description": "URL to an external report related to this insight."
},
"cloudFlowTemplateId": {
"type": "string",
"description": "ID of a CloudFlow template that can automate the remediation of this insight."
},
"easyWinDescription": {
"type": "string",
"description": "A description of why this insight is considered an easy win."
},
"status": {
"type": "string",
"enum": [
"actionable",
"acknowledged",
"optimized",
"dismissed",
"in progress",
"upgrade needed",
"permissions needed"
],
"description": "The display status of the insight."
},
"dismissalDetails": {
"type": "object",
"description": "Details for why an insight was dismissed.",
"properties": {
"reason": {
"type": "string",
"description": "The reason for dismissal.",
"enum": [
"not relevant",
"not enough information",
"not worth the effort",
"inaccurate optimization opportunities"
]
},
"comment": {
"type": "string",
"description": "An optional free-text comment providing additional context."
}
}
}
}
}
Output
Successful operation
By default dci renders the result as a table. Use --output json to get the full structure described below — see Output formats.
| Field | Type | Description |
|---|---|---|
source | string | The source that generated the insight. |
key | string | The unique key identifying this insight. |
title | string | The display title of the insight. |
shortDescription | string | A brief summary of the insight. |
detailedDescriptionMdx | string | A detailed description of the insight in MDX format. |
displayStatus | string | The display status of the insight. One of: "actionable", "acknowledged", "optimized", "dismissed", "in progress", "upgrade needed", "permissions needed". |
cloudProvider | string | The cloud provider associated with the resource. |
categories | array of string | Categories this insight belongs to. |
summary | object | Aggregate summary of risks and savings across all resource results for an insight. |
summary.operationalRisks | number (double) | Total number of operational risks. |
summary.performanceRisks | number (double) | Total number of performance risks. |
summary.potentialDailySavings | number (double) | Total potential daily savings in USD. |
summary.reliabilityRisks | number (double) | Total number of reliability risks. |
summary.securityRisks | number (double) | Total number of security risks. |
summary.sustainabilityRisks | number (double) | Total number of sustainability risks. |
lastStatusChange | object | If set, this object contains the last status change made by a user for this insight |
lastStatusChange.userId | string | the reference to the user who made the change (if it was made by a user) If the change was made by an automated system, this reference is empty. |
lastStatusChange.lastChangedAt | string (date-time) | |
lastUpdated | string (date-time) | Timestamp of the last update to this insight. |
tags | array of string | Tags for the insight, primarily used for security certification labels (e.g. ISO). |
reportUrl | string | URL to an external report related to this insight. |
cloudFlowTemplateId | string | ID of a CloudFlow template that can automate the remediation of this insight. |
easyWinDescription | string | A description of why this insight is considered an easy win. |
dismissalDetails | object | Details for why an insight was dismissed. |
dismissalDetails.reason | string | The reason for dismissal. One of: "not relevant", "not enough information", "not worth the effort", "inaccurate optimization opportunities". |
dismissalDetails.comment | string | An optional free-text comment providing additional context. |
Raw JSON schema
{
"type": "object",
"description": "An insight result containing summary information and metadata.",
"properties": {
"source": {
"type": "string",
"description": "The source that generated the insight.",
"example": "aws-trusted-advisor, aws-cost-optimization-hub, aws-security-hub, azure-advisor, custom, gcp-recommender"
},
"key": {
"type": "string",
"description": "The unique key identifying this insight."
},
"title": {
"type": "string",
"description": "The display title of the insight."
},
"shortDescription": {
"type": "string",
"description": "A brief summary of the insight."
},
"detailedDescriptionMdx": {
"type": "string",
"description": "A detailed description of the insight in MDX format."
},
"displayStatus": {
"type": "string",
"enum": [
"actionable",
"acknowledged",
"optimized",
"dismissed",
"in progress",
"upgrade needed",
"permissions needed"
],
"description": "The display status of the insight."
},
"cloudProvider": {
"type": "string",
"example": "aws",
"description": "The cloud provider associated with the resource."
},
"categories": {
"description": "Categories this insight belongs to.",
"type": "array",
"items": {
"type": "string",
"description": "The insight category.",
"enum": [
"FinOps",
"Operational excellence",
"Performance efficiency",
"Reliability",
"Security",
"Sustainability"
]
}
},
"summary": {
"type": "object",
"description": "Aggregate summary of risks and savings across all resource results for an insight.",
"properties": {
"operationalRisks": {
"type": "number",
"format": "double",
"description": "Total number of operational risks."
},
"performanceRisks": {
"type": "number",
"format": "double",
"description": "Total number of performance risks."
},
"potentialDailySavings": {
"type": "number",
"format": "double",
"description": "Total potential daily savings in USD."
},
"reliabilityRisks": {
"type": "number",
"format": "double",
"description": "Total number of reliability risks."
},
"securityRisks": {
"type": "number",
"format": "double",
"description": "Total number of security risks."
},
"sustainabilityRisks": {
"type": "number",
"format": "double",
"description": "Total number of sustainability risks."
}
}
},
"lastStatusChange": {
"description": "If set, this object contains the last status change made by a user for this insight",
"type": "object",
"properties": {
"userId": {
"description": "the reference to the user who made the change (if it was made by a user) If the change was made by an automated system, this reference is empty.\n",
"type": "string",
"example": "/users/0Rkrkeq5P0XLe8QFHKq2"
},
"lastChangedAt": {
"type": "string",
"format": "date-time"
}
},
"required": [
"userId",
"lastChangedAt"
]
},
"lastUpdated": {
"type": "string",
"format": "date-time",
"description": "Timestamp of the last update to this insight."
},
"tags": {
"description": "Tags for the insight, primarily used for security certification labels (e.g. ISO).",
"type": "array",
"items": {
"type": "string"
}
},
"reportUrl": {
"type": "string",
"description": "URL to an external report related to this insight."
},
"cloudFlowTemplateId": {
"type": "string",
"description": "ID of a CloudFlow template that can automate the remediation of this insight."
},
"easyWinDescription": {
"type": "string",
"description": "A description of why this insight is considered an easy win."
},
"dismissalDetails": {
"type": "object",
"description": "Details for why an insight was dismissed.",
"properties": {
"reason": {
"type": "string",
"description": "The reason for dismissal.",
"enum": [
"not relevant",
"not enough information",
"not worth the effort",
"inaccurate optimization opportunities"
]
},
"comment": {
"type": "string",
"description": "An optional free-text comment providing additional context."
}
}
}
}
}
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 status | Exit code | Error code | Meaning |
|---|---|---|---|
| 400 | 30 | VALIDATION_ERROR | The arguments or request body were rejected. Review the command's flags and payload. |
| 401 | 10 | AUTHENTICATION_FAILED | Not signed in, or the API token is invalid. Run dci login or check DCI_API_KEY. |
| 403 | 11 | PERMISSION_DENIED | The DoiT user or the active customer context does not have access. |
| 500 | 40 | API_SERVER_ERROR | The API failed to process the request. Retryable; contact DoiT support if it persists. |
Related
- replace-insight-resource-results — Replace resource results for an insight
- get-insight — Retrieve an insight
- list-insights — List insights
- create-insights — Create insights (batch)
- delete-insight — Delete an insight
- API reference: POST /insights/v1/results/source/{sourceID}/insight/{insightKey}
Aliases: post-insight-result