Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Analyze and reduce Azure cloud costs by right-sizing resources, reservations, and spending policies
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
cost-query/guardrails.md
1# Cost Query Guardrails23Detailed validation rules and guardrails for the Cost Management Query API. The system applies these automatically, but understanding them helps avoid unexpected query modifications or errors.45## Time Period Validation67### Default Behavior89| Scenario | System Behavior |10|----------|----------------|11| No time period specified | Defaults to current month start → today. |12| `from` is after `to` | System silently swaps `from` and `to`. |1314### Future Date Handling1516| Scenario | System Behavior |17|----------|----------------|18| Both `from` and `to` are in the future | Entire period shifted to the equivalent period last year. |19| Only `to` is in the future | `to` is adjusted to today's date. |2021> ⚠️ **Warning:** Future date shifting happens silently. The response data will cover the adjusted period, not the originally requested dates.2223### Granularity-Based Range Limits2425| Granularity | Maximum Range | Truncation Behavior |26|-------------|---------------|---------------------|27| `Daily` | 31 days | `from` truncated to `to - 1 month + 1 day`. |28| `Monthly` | 12 months | `from` truncated to `to - 12 months + 1 day`. |29| `None` | 12 months | `from` truncated to `to - 12 months + 1 day`. |3031> ⚠️ **Warning:** The absolute API limit is **37 months**. Requests exceeding 37 months return HTTP 400 regardless of granularity.3233### Minimum Start Date3435| Constraint | Value |36|------------|-------|37| Earliest allowed `from` date | May 1, 2014 |3839### GroupBy Interaction with Time Period4041| Combination | System Behavior |42|-------------|----------------|43| GroupBy + Daily granularity | Time period adjusted to the last day of the requested range. |44| GroupBy + Monthly granularity | Time period adjusted to the last month of the requested range. |4546> 💡 **Tip:** When using GroupBy with Daily granularity over a multi-day range, the system may return data only for the last day. For full daily breakdown with grouping, ensure the range is within the 31-day limit.4748## ResourceId Scope Restriction4950> ⚠️ **Warning:** Grouping by `ResourceId` is **only supported at subscription scope and below** (subscription, resource group). It is NOT supported at higher scopes.5152| Scope | ResourceId GroupBy |53|-------|--------------------|54| Subscription | ✅ Supported |55| Resource Group | ✅ Supported |56| Billing Account | ❌ Not supported |57| Management Group | ❌ Not supported |58| Billing Profile | ❌ Not supported |59| Department (EA) | ❌ Not supported |60| Enrollment Account (EA) | ❌ Not supported |61| Invoice Section (MCA) | ❌ Not supported |62| Customer (Partner) | ❌ Not supported |6364When the user requests a cost breakdown by resource at a billing account or management group scope, use `ServiceName`, `SubscriptionName`, or another supported dimension instead. If per-resource detail is needed, narrow the scope to a specific subscription first.6566## Dataset Validation6768### GroupBy Constraints6970| Rule | Limit | Error Behavior |71|------|-------|----------------|72| Maximum GroupBy dimensions | 2 | Validation error if more than 2 specified. |73| Duplicate columns in GroupBy | Not allowed | Validation error on duplicate column names. |74| Same column in Aggregation and GroupBy | Not allowed | Validation error if a column appears in both. |7576### Aggregation Constraints7778| Rule | Details |79|------|---------|80| Standard queries aggregation function | Only `Sum` is allowed. |81| `Date` in aggregation with granularity | Not allowed. Cannot aggregate on `Date` when granularity is `Daily` or `Monthly`. |8283### Filter Constraints8485| Rule | Details |86|------|---------|87| `and` operator | Must have 2 or more child expressions. |88| `or` operator | Must have 2 or more child expressions. |89| `not` operator | Must have exactly 1 child expression. |9091> ⚠️ **Warning:** A filter with a single child in `and` or `or` will fail validation. Wrap single-condition filters directly without a logical operator, or use `not` for negation.9293## Scope & Dimension Compatibility9495Dimensions must be valid for the intersection of the agreement type **and** scope type.9697| Agreement Type | Unique Dimensions | Reference |98|----------------|-------------------|-----------|99| EA | `DepartmentName`, `EnrollmentAccountName`, `BillingPeriod` | See [dimensions-by-scope.md](dimensions-by-scope.md) |100| MCA | `InvoiceSectionName` | See [dimensions-by-scope.md](dimensions-by-scope.md) |101| MOSP | _(common dimensions only)_ | See [dimensions-by-scope.md](dimensions-by-scope.md) |102103| Validation | Error Behavior |104|------------|----------------|105| Dimension not valid for agreement type | `BillingSubscriptionNotFound` or dimension validation error. |106| Dimension not valid for scope type | `BadRequest` with invalid dimension message. |107108> ⚠️ **Warning:** Using an EA-only dimension (e.g., `DepartmentName`) on a MOSP subscription will return a validation error. Always verify the agreement type before selecting dimensions.109110## EA + Management Group Special Case111112| Scenario | Result |113|----------|--------|114| Filter by `SubscriptionName` without `SubscriptionId` at Management Group scope | Error returned. |115| Error message | _"To view cost data, the subscription ID is needed. Select Subscriptions to find the ID for your subscription, and then ask your question again."_ |116117**Remediation:** When filtering by subscription name at Management Group scope under EA, always include a `SubscriptionId` filter alongside the `SubscriptionName` filter.118119```json120{121"and": [122{123"dimensions": {124"name": "SubscriptionId",125"operator": "In",126"values": ["<subscription-id>"]127}128},129{130"dimensions": {131"name": "SubscriptionName",132"operator": "In",133"values": ["My Subscription"]134}135}136]137}138```139140## Rate Limiting141142### Rate Limit Thresholds143144| Limit | Value |145|-------|-------|146| Per User | 20 requests per minute |147| Per Scope | 4 requests per minute |148| Per Tenant | 12 requests per 10 seconds, 60 requests per minute, 600 requests per hour |149| Per Client Type | 2,000 requests per minute |150151> ⚠️ **Warning:** The **per-scope limit (4 requests/minute)** is the most restrictive. Sequential queries to the same subscription, resource group, or billing account share this limit.152153### QPU-Based Throttling154155| Tier | Description |156|------|-------------|157| Premium | Higher QPU allocation (EA, MCA enterprise). |158| Non-premium | Lower QPU allocation (MOSP, trial). |159160### Rate Limit Headers161162| Header | Description |163|--------|-------------|164| `x-ms-ratelimit-microsoft.costmanagement-qpu-retry-after` | Seconds to wait before retrying (QPU limit). |165| `x-ms-ratelimit-microsoft.costmanagement-entity-retry-after` | Seconds to wait before retrying (entity/scope limit). |166| `x-ms-ratelimit-microsoft.costmanagement-tenant-retry-after` | Seconds to wait before retrying (tenant limit). |167168### Handling 429 Responses169170On a 429 response, check **all** retry-after headers present in the response. Multiple headers may be returned simultaneously. Take the **maximum** value and **do NOT send any further requests to the same scope until that duration has fully elapsed.**171172> ⚠️ **Warning:** Do not retry before the retry-after duration has elapsed. Premature retries will be rejected and may extend the throttling period.173174### Pagination175176| Parameter | Default | Maximum |177|-----------|---------|---------|178| Page size | 1,000 rows | 5,000 rows |179| Pagination | Use `nextLink` from response to fetch subsequent pages. | — |180181> 💡 **Tip:** For large result sets, always check the `nextLink` field in the response. If present, make additional requests to retrieve all pages.182