API REFERENCE

Grouped Forecasting.

Forecast a set of related series that combine into a total, such as MRR by plan and region, demand by warehouse, or revenue by category. You receive one coherent result: every parent equals the sum of its children, in every period, at every level.

Why a dedicated endpoint
Forecast five segments and the total independently, and the numbers do not sum correctly. Each series picks its own model and trend. This is acceptable for exploration, but not for a board deck. Grouped forecasting reconciles the whole hierarchy, so the parts sum to the whole by construction.

How it works

You send the leaves of your hierarchy. The leaves are every combination of the dimensions that you declare, each with its own history. The API then sums the leaf histories to derive every aggregate level, such as each region and the grand total. The API forecasts the nodes, reconciles them to coherence, and stores each node as its own entity with independently tracked accuracy.

The run is asynchronous. When you submit a hierarchy, the API returns 202 with an id to poll, and the run executes in the background as one all-or-nothing job. A hierarchy is one coherent answer, so there is no partial success. If any node cannot be forecast, the run fails with the reason. It does not return numbers that do not sum correctly.

Submit a hierarchy

/v2/forecast/grouped POST /v2/forecast/grouped

The identifier names the measure. Each series carries a structured segment that names exactly the declared hierarchy dimensions. segment is independent of tenant_context. Tenancy still means "whose data is this", and segment means "which slice".

REQUEST POST /v2/forecast/grouped
{
  "identifier": "mrr",
  "hierarchy": ["region", "plan"],
  "reconciliation": "bottom_up",
  "frequency": "M",
  "periods": 6,
  "data_type": "revenue",
  "series": [
    {"segment": {"region": "eu", "plan": "pro"},
     "data": [{"date": "2024-01-01", "value": 42000}, {"date": "2024-02-01", "value": 43800}]},
    {"segment": {"region": "eu", "plan": "free"},
     "data": [{"date": "2024-01-01", "value": 3100}, {"date": "2024-02-01", "value": 3300}]},
    {"segment": {"region": "us", "plan": "pro"},
     "data": [{"date": "2024-01-01", "value": 61000}, {"date": "2024-02-01", "value": 62500}]}
  ]
}
RESPONSE 202 ACCEPTED
{
  "grouped_forecast_id": "k3n9x2m4p8q1w5r7",
  "status": "pending",
  "series_count": 3,
  "node_count": 6,
  "reconciliation": "bottom_up",
  "time_taken_ms": 41.2
}

node_count is the number of nodes that the API forecasts and reconciles. It counts the leaves plus every derived aggregate and the total. The three series above expand to six nodes: total, two regions, and three leaves. A request may expand to at most 250 nodes.

Poll for the result

/v2/forecast/grouped/{id} GET /v2/forecast/grouped/{id}

This endpoint returns the run status. When the run is completed, it also returns a node map keyed by segment (total, region=eu, plan=pro|region=eu, …). Every node carries its own forecast rows, its place in the tree, and the reconciliation details.

RESPONSE 200 OK
{
  "grouped_forecast_id": "k3n9x2m4p8q1w5r7",
  "status": "completed",
  "node_count": 6,
  "results": {
    "identifier": "mrr",
    "hierarchy": ["region", "plan"],
    "reconciliation": {"method": "bottom_up", "correlation": 0.5, "correlation_source": "default", "measured": false},
    "confidence_level": 0.8,
    "nodes": {
      "total": {
        "segment": {},
        "parent": null,
        "children": ["region=eu", "region=us"],
        "forecasts": [{"period": 1, "date": "2024-07-01", "forecast": 118400.0, "lower": 112300.5, "upper": 124499.5}]
      },
      "region=eu": {
        "segment": {"region": "eu"},
        "parent": "total",
        "children": ["plan=free|region=eu", "plan=pro|region=eu"],
        "forecasts": [{"period": 1, "date": "2024-07-01", "forecast": 51900.0, "lower": 48700.2, "upper": 55099.8}]
      }
    }
  }
}

Reconciliation methods

bottom_up (default)
The API forecasts only the leaves. Every aggregate is the exact sum of its children. This method is quick and cheap, and the leaves keep their own models unchanged. Use it when the leaf histories are long enough to forecast well on their own.
min_trace
The API forecasts every node, including the aggregates. MinTrace then optimally redistributes the disagreement between levels into a coherent set. This method costs one forecast per node. It lets the usually smoother aggregate series inform the result, which tends to help when the leaves are short or noisy. Each node reports its unreconciled path under model_info.reconciliation.base_forecast.

Confidence bands on aggregates

Summing the children's lower values is not a lower bound for the parent. That sum assumes every child misses low at once. With bottom_up, the API instead builds an aggregate band from its children's uncertainties under a stated correlation assumption between sibling errors (correlation, default 0.5, overridable per request between 0 and 1). The response echoes this assumption and never labels it as measured. With min_trace, each node keeps its own band, re-centered on the reconciled point with its width preserved.

NOTE
When a node's band coverage is unknown (a heuristic interval), the API emits no aggregate band above it. It states the reason in model_info.reconciliation.interval_reason. This is an honest absence rather than a decorative interval.

Rules and limits

  • Every series must declare exactly the hierarchy dimensions in its segment, and each combination may appear once.
  • All series must end on the same date so the forecast periods align. A history may start at any date. A segment that launched later contributes zero before its first data point.
  • periods, frequency, model and confidence are request-level only. Every node of a hierarchy must share them, so the API rejects per-series overrides instead of ignoring them silently. For the same reason, the API does not accept model: auto here. It routes per series, and the API reconciles a hierarchy under one model.
  • Up to 4 hierarchy levels and 250 expanded nodes per request (10 leaf series on the free plan).
  • Grouped forecasts do not yet support quantiles, value_bounds, adjustments and accumulate. The API rejects them explicitly.
Segments without reconciliation?
If you want independent forecasts per slice with no coherent total, use the batch endpoint with per-series identifiers or tenant_context. It is simpler and tolerates per-series failure. See Patterns & Segmentation.
LAST UPDATED — 03 SEP 2026 · FORECASTAPI DOCS
WAS THIS USEFUL? YES NO