Subchapter 13.22
cost-query/workflow.mdMarkdown5 KBView on GitHub
Use this workflow when the user wants to understand their costs — breakdowns, trends, totals, top spenders.
Identify the Azure scope for the cost query from the Scope Reference table in the main SKILL.md.
| Type | Description |
|---|---|
ActualCost | Actual billed costs including purchases |
AmortizedCost | Reservation/savings plan costs spread across usage period |
Usage | Usage-based cost data |
Use a preset timeframe (e.g., MonthToDate, TheLastMonth, TheLastYear) or Custom with a timePeriod object.
⚠️ Warning: Key time period guardrails:
- Daily granularity: max 31 days
- Monthly/None granularity: max 12 months
Customtimeframe requires atimePeriodobject withfromandtodates- Future dates in historical queries are silently adjusted (see guardrails for details)
See guardrails.md for the complete set of validation rules.
Define granularity, aggregation, grouping, filtering, and sorting in the dataset object.
None, Daily, or MonthlySum on Cost or PreTaxCost for total costGroupBy dimensions (e.g., ServiceName, ResourceGroupName)dimensions or tags filters with name, operator (In, Equal, Contains), and values fields💡 Tip: Not all dimensions are available at every scope. See dimensions-by-scope.md for the availability matrix.
For the full request body schema, see request-body-schema.md.
Use az rest to call the Cost Management Query API.
Create cost query file:
Create temp/cost-query.json with:
{
"type": "ActualCost",
"timeframe": "MonthToDate",
"dataset": {
"granularity": "None",
"aggregation": {
"totalCost": {
"name": "Cost",
"function": "Sum"
}
},
"grouping": [
{
"type": "Dimension",
"name": "ServiceName"
}
]
}
}Execute cost query:
# Create temp folder
New-Item -ItemType Directory -Path "temp" -Force
# Query using REST API (more reliable than az costmanagement query)
az rest --method post `
--url "<scope>/providers/Microsoft.CostManagement/query?api-version=2023-11-01" `
--headers "ClientType=GitHubCopilotForAzure" `
--body '@temp/cost-query.json'nextLink is present in the response, follow it to retrieve additional pages.x-ms-ratelimit-microsoft.costmanagement-*-retry-after headers in the response. Wait for the longest value before retrying. Do not send further requests to the same scope until the retry-after duration has elapsed.See error-handling.md for the full error reference.
| Rule | Constraint |
|---|---|
| Daily granularity max range | 31 days |
| Monthly/None granularity max range | 12 months |
| Absolute API max range | 37 months |
| Max GroupBy dimensions | 2 |
| ResourceId grouping scope | Subscription and resource group only — not supported at billing account, management group, or higher scopes |
| Max rows per page | 5,000 |
| Custom timeframe | Requires timePeriod with from/to |
| Filter and/or | Must have at least 2 expressions |
Cost by service for the current month:
az rest --method post `
--url "/subscriptions/<subscription-id>/providers/Microsoft.CostManagement/query?api-version=2023-11-01" `
--headers "ClientType=GitHubCopilotForAzure" `
--body '{
"type": "ActualCost",
"timeframe": "MonthToDate",
"dataset": {
"granularity": "None",
"aggregation": {
"totalCost": { "name": "Cost", "function": "Sum" }
},
"grouping": [
{ "type": "Dimension", "name": "ServiceName" }
]
}
}'For more examples including daily trends, tag-based filtering, and multi-dimension queries, see examples.md.
| HTTP Status | Error | Remediation |
|---|---|---|
| 400 | Invalid request body | Check schema, date ranges, and dimension compatibility. |
| 401 | Unauthorized | Verify authentication (az login). |
| 403 | Forbidden | Ensure Cost Management Reader role on scope. |
| 404 | Scope not found | Verify scope URL and resource IDs. |
| 429 | Too many requests | Check all x-ms-ratelimit-microsoft.costmanagement-*-retry-after headers (qpu, entity, tenant). Wait for the longest value. Max 3 retries. |
| 503 | Service unavailable | Check Azure Status (opens in a new tab). |
See error-handling.md for detailed error handling including rate limit headers and retry strategies.