---
title: "Evaluate static 2025 forecasts or rolling D-2 historical backtests within 2020–2025"
method: POST
path: "/api/forecast-sandbox/consumption/evaluation/run"
tags: ["Forecast Sandbox"]
---

# Evaluate static 2025 forecasts or rolling D-2 historical backtests within 2020–2025

`POST /api/forecast-sandbox/consumption/evaluation/run`

## Request

- Base URL: `https://api.cernion.de`
- URL: `https://api.cernion.de/api/forecast-sandbox/consumption/evaluation/run`
- Auth: none declared

REST returns HTTP 202 and the standard /api/jobs status/progress/result URLs. Poll until completed or error; progress reports completed forecast days, not elapsed-time estimates. Internal broker calls await the result. Stateless sandbox evaluation. Explicit timezone, DST-aware local days. JSON export includes curves, training cutoffs, metrics and readiness dossier. No SLA or commercial commitment. API body limit: 25 MB; split series across requests when necessary.

## Query parameters

- `token` string

## Request body

- object
  - `datasets` object[], required
    - `series_id` string, required: Pseudonymous identifier; no personal data.
    - `timezone` string, required
    - `unit` 'kW' | 'kWh', required
    - `customer_type` string
    - `segment` string
    - `weather_region` string
    - `period_from` string, date
    - `period_until` string, date
    - `field_mapping` object
      - `timestamp` string
      - `value` string
    - `values` object[], required
      - `timestamp` string, date-time, required: Interval start with explicit offset or Z.
      - `value` number, nullable, required
      - `available_at` string, date-time: Actual historical availability of this measurement/revision.
      - `quality_flag` string
  - `payload_fit_confirmed` boolean, required: Explicit confirmation after reviewing validation.
  - `configuration` object, required
    - `extended_features` boolean: Include season in automatic candidate selection.
    - `issue_time` '00:00' | '07:00' | '18:00': Local D-1 issue time; meter history always ends D-2.
    - `weather_dataset_id` string
    - `context_dataset_id` string
    - `context` object: Versioned source/region plus rows with timestamp, available_at, day_ahead_price EUR/MWh or grid_load_lag2 MW and source_period_until.
    - `mode` 'static_year_forecast' | 'rolling_day_ahead', required
    - `model_family` 'relationship' | 'learned_states': learned_states: nonnegative rolling auto forecast; version relationship_state_correction_v2 adds a past-validated state correction to automatic calendar/recency selection. RMSE gate and MAE guard every 28 days; daily reference fits. API persists the combined snapshot. Version relationship_state_context_guard_v4 supports optional weather/context and 18:00 origins; additional features must improve on the existing automatic model.
    - `relationship_mode` 'auto' | 'manual': Per-series automatic predictor selection using historical forward validation, independent confirmation and conditional ablation. Manual retains the original configured profile baseline.
    - `history_from` string, date
    - `selection_policy` 'adaptive_rmse_v1': Opt-in RMSE objective; compare 28/84/365 days and all eligible history with temporal confirmation and MAE guard.
    - `prediction_threshold_w` number: Prediction-only deadband in watts. Strictly smaller absolute predictions become zero; actuals and training remain unchanged. 50 W = 0.05 kW = 0.0125 kWh per PT15M. 0 disables filtering. Persisted with state-model artifacts.
    - `activity_model` boolean: With adaptive_rmse_v1, test separate activity-probability and positive-amount models for nonnegative histories with at least 20% zeros. Persisted and enabled only after confirmation.
    - `activity_labeling` 'learned_low_load_v1': Opt-in training-only near-zero labels, activity classifier and separate low/active amount trees. Requires activity_model and adaptive_rmse_v1. Each historical fold learns its own threshold; held-out RMSE gain and no MAE regression required. Negative net flows are excluded. Omit to retain exact-zero activity modeling.
    - `selection_metric` 'mae' | 'rmse': Automatic selection objective, consistently used for discovery, confirmation and conditional ablation. Both MAE and RMSE are always reported.
    - `recent_window_days` 28 | 84: Alternative recent-history window tested against full eligible history. It is used only if independently confirmed; this does not alter D-2.
    - `forecast_period_from` string, date, required: Rolling historical backtests support 2020–2025; static forecasts require 2025. Training remains strictly prior to each forecast cutoff.
    - `forecast_period_until` string, date, required
    - `feature_set` string[]: Allowed feature families. Auto default: history and derived calendar, plus weather when supplied. Supplying history alone intentionally disables calendar/weather discovery.
    - `calendar` object
      - `source` string, required
      - `version` string, required
      - `country` string, required
      - `region` string, required
      - `features` string[]
      - `days` object[]
        - `date` string, date, required
        - `holiday` boolean
        - `special_day` string
        - `bridge_day` boolean
        - `school_holiday` boolean
        - `known_at` string, date-time
    - `weather` object
      - `source` string, required
      - `version` string, required
      - `region` string, required
      - `observations` object[]: Requires available_at per observation.
        - `timestamp` string, date-time, required
        - `temperature` number: Degrees Celsius.
        - `heating_degree_days_18` number: Daily mean heating deficit, base 18 Celsius, K.d.
        - `humidity` number: Relative humidity in percent.
        - `wind_speed` number: Metres per second.
        - `global_radiation` number: Watts per square metre.
        - `cloud_cover` number: Cloud cover in percent.
        - `precipitation` number: Millimetres per PT15M interval.
        - `issued_at` string, date-time
        - `available_at` string, date-time
      - `forecasts` object[]: Archived forecasts; requires issued_at per forecast.
        - `timestamp` string, date-time, required
        - `temperature` number: Degrees Celsius.
        - `heating_degree_days_18` number: Daily mean heating deficit, base 18 Celsius, K.d.
        - `humidity` number: Relative humidity in percent.
        - `wind_speed` number: Metres per second.
        - `global_radiation` number: Watts per square metre.
        - `cloud_cover` number: Cloud cover in percent.
        - `precipitation` number: Millimetres per PT15M interval.
        - `issued_at` string, date-time
        - `available_at` string, date-time
  - `token` string: Optional Cernion MCP token for this request. Overrides CERNION_TOKEN when provided.

## Response `200`

Evaluation or data validation result.

- object
  - `status` string, required
  - `testcaseBoundary` object, required
  - `validations` object[]
  - `results` object[]
    - `forecast_run` object
    - `validation` object
    - `forecast_values` object[]
      - `timestamp` string, date-time
      - `predicted_value` number: Final prediction after optional threshold filtering.
      - `raw_predicted_value` number: Unfiltered prediction; present when prediction_threshold_w > 0.
      - `prediction_zeroed` boolean: True only when a nonzero raw prediction was set to zero.
      - `actual_value` number, nullable
      - `deviation` number, nullable
      - `training_data_until` string, date-time
    - `daily_results` object[]
    - `backtest` object: Metrics for final predictions against unchanged actual measurements.
    - `filter_evaluation` object: Present when filtering is enabled: threshold_w, threshold_value, unit, changed_intervals, actuals_modified=false, raw_backtest and filtered_backtest.
    - `deviation_energy` object
    - `readiness_dossier` object
    - `relationship_analysis` object, nullable
      - `version` string
      - `causal_claim` boolean
      - `selections` object[]
        - `selection_id` string
        - `as_of` string, date-time
        - `status` 'validated_relationships' | 'baseline_retained' | 'insufficient_evidence'
        - `selected_groups` string[]
        - `selected_window_days` integer, nullable: Null means all eligible history, no arbitrary truncation.
        - `historical_quality` object: Untouched historical confirmation MSE/RMSE/MAE; available without 2025 actuals when history is sufficient.
        - `relationships` object[]
        - `candidates` object[]

## Other responses

- `202`: Forecast job accepted. Poll statusUrl/progressUrl; fetch resultUrl once completed. CPU work runs in a separate worker.
- `400`: Structured validation/configuration failure with status, error and testcaseBoundary.
- `500`: Unexpected evaluation failure; internal details are not returned.

---

[API](https://skmtc.dev/cernion/apis/cernion-energy-tools-api.md) · [All operations](https://skmtc.dev/cernion/apis/cernion-energy-tools-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cernion/apis/cernion-energy-tools-api/revisions/cdb94473b538?raw)
