Prediction Intervals
By default /v1/forecast returns only the point forecast y_hat. Pass level in the request and each forecast point also carries intervals at those levels.
1. The level parameter
level is a list of integers from 1 to 99, for example [80, 90]. Duplicates are merged and order does not matter.
Each level L maps to two model quantiles:
| Bound | Quantile | L = 80 | L = 90 |
|---|---|---|---|
lo | 0.5 − L / 200 | 0.10 | 0.05 |
hi | 0.5 + L / 200 | 0.90 | 0.95 |
2. Native quantiles
The model can only produce the quantiles it was trained with; the service never interpolates:
| Model | Native quantiles | Levels delivered as requested |
|---|---|---|
hora-1.0 | 0.01, 0.05, 0.10, 0.15 … 0.90, 0.95, 0.99 | 10, 20 … 80, 90, 98 |
When a requested quantile is not in the list, quantile_policy decides what happens.
3. quantile_policy (Beta)
| Value | Behavior |
|---|---|
nearest (default) | The nearest native quantile is used instead (on a tie, the one farther from the median), and the interval key is labelled with the quantiles actually used, not the requested level. |
strict | If any quantile is not native, the call returns 422 QUANTILE_UNSUPPORTED before inference and before any quota is reserved; nothing is billed. |
For example, level: [80, 95]: 80 maps to 0.1 and 0.9, which are native; 95 needs 0.025 and 0.975, which under nearest become 0.01 and 0.99, so the response has the keys "80" and "98" and no "95".
Under strict the error lists the unsupported quantiles and the ones the model supports:
{
"error": {
"code": "QUANTILE_UNSUPPORTED",
"message": "Model 'hora-1.0' does not natively produce quantile levels [0.025, 0.975]",
"request_id": "req_…",
"details": {
"model": "hora-1.0",
"level": [95],
"unsupported": [0.025, 0.975],
"supported": [0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 0.99]
}
}
}4. Response shape
intervals is an object keyed by a level string: the coverage between the two quantiles actually used, (hi − lo) × 100. Without level, forecast points have no intervals field.
{
"unique_id": "meter-001",
"ds": "2026-09-03T00:00:00Z",
"y_hat": 140.2,
"intervals": {
"80": {"lo": 133.9, "hi": 146.8},
"90": {"lo": 131.7, "hi": 148.9}
}
}lois never greater thanhi.- Levels that resolve to the same pair of native quantiles appear once; a level whose both bounds resolve to the median has no interval.
- Intervals come from the same model run as the point forecast and cost nothing extra.
The response also carries a top-level quantile_report (Beta) listing the requested quantiles, the quantiles actually used and every substitution:
{
"quantile_report": {
"policy": "nearest",
"requested": [0.025, 0.1, 0.5, 0.9, 0.975],
"used": [0.01, 0.1, 0.5, 0.9, 0.99],
"substitutions": [
{"requested": 0.025, "used": 0.01},
{"requested": 0.975, "used": 0.99}
]
}
}5. Point quantile point_quantile (Beta)
y_hat is the model's median (quantile 0.5) by default, not the expected value. When you need a more conservative or more optimistic point forecast (for example P70 for stocking), send point_quantile and y_hat becomes that quantile:
- 0.01 to 0.99 with at most 3 decimal places (for example
0.7or0.025). Out-of-range values, more decimals, booleans or strings return 422VALIDATION_ERRORwithdetails.errors[].fieldpoint_quantile. - Like
level, it is mapped to the model's native quantiles underquantile_policy, never interpolated:nearestuses the nearest native quantile (0.33 is served by 0.35), and a tie goes to the one farther from the median;strictrejects a non-native value with 422QUANTILE_UNSUPPORTEDbefore any quota is reserved, withdetails.point_quantileset to the requested value. - It is independent of
level, soy_hatcan lie outside an interval (for examplepoint_quantile: 0.95withlevel: [80]). - Without it, behavior and response are unchanged. With it, the response echoes the quantile actually served as top-level
point_quantile,quantile_report.requested,usedandsubstitutionsinclude it, andquantile_report.point_forecastis added. Not billed extra.
{
"model": "hora-1.0",
"series": [ … ],
"h": 24,
"level": [80],
"point_quantile": 0.33
}{
"model_used": "hora-1.0",
"point_quantile": 0.35,
"forecast": [
{"unique_id": "meter-001", "ds": "2026-09-03T00:00:00Z", "y_hat": 145.1,
"intervals": {"80": {"lo": 133.9, "hi": 146.8}}}
],
"quantile_report": {
"policy": "nearest",
"requested": [0.1, 0.33, 0.5, 0.9],
"used": [0.1, 0.35, 0.5, 0.9],
"substitutions": [{"requested": 0.33, "used": 0.35}],
"point_forecast": {"requested": 0.33, "used": 0.35, "method": "nearest"}
}
}