Predict.aiDocs
Goals

Forecast

Read the goal's live forecast and track record, force a refresh, and see the pressure behind it.

Once a champion is deployed, the goal has a forecast — refreshed on the goal's cadence while data keeps arriving.

Get the forecast

curl "$API_BASE/v1/goals/$GOAL_ID/forecast" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"
{
  "data": {
    "goal_id": "b7e9c2d4-…",
    "goal_name": "Daily sales",
    "goal_type": "forecast_value",
    "target_key": "daily_sales",
    "interval_seconds": 86400,
    "horizon_bins": 14,
    "champion_pipeline_id": "9f2c41d8-…",
    "shock_state": "normal",
    "shock_stream": null,
    "forecast": {
      "at": "2026-07-15T06:00:12+00:00",
      "inference_uid": "3f1a…",
      "training_id": "t_5b2e…",
      "interval_seconds": 86400,
      "horizon_bins": 14,
      "serving_mode": "forecast",
      "unit": "$",
      "point": [13102.4, 13350.9, 13571.2, "…"],
      "quantiles": {
        "0.1": [12480.1, 12633.7, "…"],
        "0.9": [13724.9, 14068.2, "…"]
      },
      "history": {
        "values": [12841.5, 12933.0, "…"],
        "step_at": ["2026-07-13T00:00:00+00:00", "2026-07-14T00:00:00+00:00", "…"]
      },
      "step_at": ["2026-07-16T00:00:00+00:00", "2026-07-17T00:00:00+00:00", "…"],
      "model_quality": {
        "accuracy_score": 91.4,
        "skill_score": 34.2,
        "score_kind": "smape"
      }
    },
    "track_record": {
      "horizon_accuracy": [{ "step": 1, "accuracy": 94.1 }, "…"],
      "interval_coverage": 0.87
    }
  }
}

Response fields

FieldMeaning
forecast.point / forecast.step_atThe chart-ready path: one value and one timestamp per horizon step.
forecast.quantilesUncertainty bands keyed by level, when the champion produces them.
forecast.historyAn inlined snapshot of recent actuals, for context to the left of the forecast.
forecast.serving_modeHow to read the numbers — forecast for level goals, a probability in [0, 1] for trend and anomaly goals.
forecast.model_qualityThe champion's held-out accuracy_score and skill_score (value over a naive baseline).
track_recordThe nightly-aggregated honesty check: how past forecasts actually scored per horizon step, and how often actuals landed inside the quantile band (interval_coverage).
shock_state / shock_streamFlips from normal when a shock protocol is active — see shock analogues.

forecast is null until a champion exists; if a champion is live but hasn't been invoked yet, this read serves one on demand so it's never empty. shock_state flips from normal when a shock protocol is active — see shock analogues below.

This endpoint is a rich studio read. For production integrations, call the inference goal aliasPOST /v1/inference/goals/{goal_id}/infer-segment — which always routes to the current champion, so your URL survives champion swaps and re-deployments.

Force a fresh forecast

The GET only serves on demand when no forecast exists. To re-infer on the newest data even if the stream hasn't advanced:

curl -X POST "$API_BASE/v1/goals/$GOAL_ID/forecast/rerun" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"

The response is the same shape as the GET, plus "reran": true. Returns 409 with "No deployed model to run — this goal has no champion yet." until a champion is live.

Why this forecast: drivers-now

The validated graph projected as current pressure — each driver's latest value, its move over its own validated lag, and the direction it's pushing the target. Computed deterministically from stored edge evidence:

curl "$API_BASE/v1/goals/$GOAL_ID/drivers-now" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"
{
  "data": {
    "drivers": [
      {
        "key": "ad_spend",
        "kind": "signal",
        "edge_id": "7d3f…",
        "lifecycle": "validated",
        "direction": "positive",
        "lag_bins": 3,
        "lag_seconds": 259200,
        "lift": 0.18,
        "confidence": 0.94,
        "impact": 0.61,
        "tier": "validated",
        "current_value": 8420.0,
        "value_at_lag": 7630.0,
        "change_pct": 10.35,
        "pressure": "upward",
        "narrative": "ad_spend rose 10.4% over its 3-step lead → upward pressure now",
        "unit": "$",
        "simulatable": true
      }
    ],
    "predictive_drivers": [
      { "key": "competitor_price", "tier": "suggestive", "confidence": 0.71, "impact": 0.33, "…": "…" }
    ],
    "as_of": "2026-07-15T12:00:03+00:00",
    "interval_seconds": 86400,
    "target_unit": "$",
    "scenario_examples": { "examples": ["What if ad spend rises 10%?"] }
  }
}

Response fields

FieldMeaning
driversThe validated tier — every entry is a relationship that survived the full discovery funnel.
predictive_driversThe wider suggestive set the model can also learn from, with the same confidence-vs-impact axes.
drivers[].direction / pressureWhich way the driver pushes the target, and which way it's pushing right now given its latest move.
drivers[].lag_bins / lag_secondsThe validated lead time — how far ahead this driver moves before the target follows.
drivers[].current_value / value_at_lag / change_pctThe driver's latest value, its value one lag ago, and the move between them.
drivers[].confidence / impact / liftHow sure the platform is, how much the target responds, and the measured predictive lift.
drivers[].simulatabletrue means you can move this driver in Scenarios.
scenario_examplesReady-made what-if prompts for this goal.

Shock analogues

When one of the goal's connected event streams spikes, the goal enters a shock state and the platform attaches an analogue fan: in similar past events, here's how the target moved within 24 hours.

curl "$API_BASE/v1/goals/$GOAL_ID/shock-analogues" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"
{
  "data": {
    "goal_id": "b7e9c2d4-…",
    "shock_state": "shocked",
    "entry": {
      "entry_id": "sh_20b4…",
      "stream": "supply_disruptions",
      "entered_at": "2026-07-15T04:12:00+00:00",
      "exited_at": null,
      "analogues": [
        { "occurred_at": "2026-03-02T…", "target_move_pct": -6.2, "similarity": 0.91 }
      ]
    },
    "analogues": [
      { "occurred_at": "2026-03-02T…", "target_move_pct": -6.2, "similarity": 0.91 }
    ]
  }
}

entry and analogues are null when the goal has never shocked. The shock state also shows on the forecast read (shock_state, shock_stream) so consumers can caveat the headline number.

On this page