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-forecast/guardrails.md
1# Forecast API Guardrails23Detailed guardrails derived from CCM-LUX getForecastData and CCM-UX-MIDDLEWARE Forecaster.45## Time Period Validation67| Rule | Detail |8|---|---|9| `to` date must be in the future | `numberOfDaysToForecast` must be > 0. Entirely past date ranges return a `CantForecastOnThePast` error. |10| `from` can be in the past | When `from` is in the past, the response includes actual costs from `from` to today and forecast costs from today to `to`. |11| Both dates must be valid | When `timePeriod` is present, both `from` and `to` must be valid parseable ISO 8601 datetime strings. |12| Monthly + includeActualCost | Monthly granularity with `includeActualCost=true` requires an explicit `timePeriod` with valid `from` and `to` dates. Omitting it produces `DontContainsValidTimeRangeWhileMonthlyAndIncludeCost`. |13| Maximum forecast period | 10 years maximum forecast window. |1415> ⚠️ **Warning:** If both `from` and `to` are in the past, the API returns `CantForecastOnThePast`. At least the `to` date must be in the future.1617## Training Data Requirements1819| Requirement | Value |20|---|---|21| Minimum historical data | 4 weeks (28 days) of cost data |22| Preferred training window | Up to 3 months of history |23| Late arrival tolerance | 2 days for billing data to arrive |24| New subscriptions (< 28 days) | Forecast unavailable |2526> ⚠️ **Warning:** New subscriptions with fewer than 28 days of cost history cannot generate forecasts. Suggest using **the Cost Query workflow (Part 1)** to retrieve available historical data instead.2728## Grouping Restriction2930| Aspect | Detail |31|---|---|32| Grouping support | ❌ **Not supported** |33| API limitation | This is a hard limitation of the Forecast API. The `grouping` field is not accepted in the request body. |34| Workaround | If the user requests a grouped forecast (e.g., forecast by resource group or service), inform them that grouping is not supported for forecasts. Suggest querying historical data with grouping using **the Cost Query workflow (Part 1)** instead. |3536> ⚠️ **Warning:** Even when using **the Cost Query workflow (Part 1)** for grouped historical data, `ResourceId` grouping is only supported at subscription scope and below. It is not supported at billing account, management group, or higher scopes.3738## Response Row Limit3940| Constraint | Detail |41|---|---|42| Maximum rows | 40 rows per forecast response |43| Daily example | 30 actual days + 30 forecast days = 60 rows → **exceeds limit** |44| Recommendation | For daily granularity, keep forecast period to ~2–3 weeks |45| Longer periods | Use monthly granularity to stay within the row limit |4647> 💡 **Tip:** If the user needs a daily forecast for more than 2–3 weeks, consider splitting the request into smaller time windows or switching to monthly granularity.4849## includeActualCost / includeFreshPartialCost5051| Field | Default | Dependency |52|---|---|---|53| `includeActualCost` | `true` | None |54| `includeFreshPartialCost` | `true` | **Requires `includeActualCost=true`** |5556> ⚠️ **Warning:** Setting `includeFreshPartialCost=true` without `includeActualCost=true` produces validation error `DontContainIncludeActualCostWhileIncludeFreshPartialCost`. Always set both fields explicitly.5758## Forecast Availability5960The API returns "Forecast is unavailable for the specified time period" when:6162| Condition | Detail |63|---|---|64| Null/empty response rows | Response has no data rows |65| Insufficient training data | Scope has fewer than 28 days of cost history |66| No cost history | Scope has never had any cost data |6768> ⚠️ **Warning:** This is **not an error** — it is a valid response indicating the forecast model cannot generate predictions. Do not retry. Instead, suggest using **the Cost Query workflow (Part 1)** to retrieve whatever historical data is available.6970## Rate Limiting7172### Rate Limit Thresholds7374The Forecast API shares the same rate limits as the Cost Query API:7576| Limit | Value |77|-------|-------|78| Per User | 20 requests per minute |79| Per Scope | 4 requests per minute |80| Per Tenant | 12 requests per 10 seconds, 60 requests per minute, 600 requests per hour |81| Per Client Type | 2,000 requests per minute |8283> ⚠️ **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.8485### Rate Limit Headers8687| Header | Description |88|---|---|89| `x-ms-ratelimit-microsoft.costmanagement-qpu-retry-after` | Seconds to wait before retrying (QPU-based) |90| `x-ms-ratelimit-microsoft.costmanagement-entity-retry-after` | Seconds to wait for entity/scope-level throttle |91| `x-ms-ratelimit-microsoft.costmanagement-tenant-retry-after` | Seconds to wait for tenant-level throttle |9293### Handling 429 Responses9495On 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 retry until that duration has fully elapsed.**9697> ⚠️ **Warning:** Do not retry before the retry-after duration has elapsed. Premature retries will be rejected and may extend the throttling period.98