Energy Model Runs
POST /energymodels accepts an EnergyModelInput payload and executes a run
either synchronously or asynchronously. Saved energy-model rows can then be
edited and rerun in place with GET /energymodels/{id}?include=inputs,
PUT /energymodels/{id}, and POST /energymodels/{id}/run.
Endpoint behavior
- Sync is the default when
asyncis omitted. ?async=falseruns sync and returns200when results complete in request scope.?async=truequeues background processing and returns a queued200response.- Multi-block sync fan-out can also return a queued
200response if worker blocks do not finish within the sync wait window. - Queued async and fan-out responses do not expose per-block task IDs in the public payload.
Saved-input edit/rerun workflow
The saved-row workflow is:- Fetch the currently saved input JSON with
GET /energymodels/{id}?include=inputs - Edit the returned
inputsJSON - Save the updated JSON back to the same row with
PUT /energymodels/{id} - Rerun that same saved row with
POST /energymodels/{id}/run
PUT /energymodels/{id}updates the saved input JSON on the existing energy-model row.POST /energymodels/{id}/runruns the currently saved JSON in place on that same row.- Rerun does not create a new energy-model row.
- Imported PVsyst variants created by
POST /projects/importare intended entry points for this flow. - Active rows with status
pending,queued, orrunningreject update/rerun with409 Conflict.
Request contract
Minimum required structure:- exactly one of
projectId,locationId, or inlinelocation blockswith at least one block
inverterIdshading,losses,acSystem,albedo- at least one of
arrayordcInputs - at least one of
layoutorlayoutRef
Request compatibility and deprecation behavior
Current behavior:- top-level
name- backward-compatible alias for
output.name
- backward-compatible alias for
output.blockIndex- canonical zero-based selected-block response filter
- valid only when block-level results are effectively requested
output.blockResults- canonical block-level time-series visibility flag for
blockTimeSeries - mutually exclusive with
output.fullTimeSeries
- canonical block-level time-series visibility flag for
output.lossBreakdownTimestamps- top-level boolean request flag
- implies block-level results are surfaced
- the older object wrapper form is rejected on the public API
output.irradianceLossDetail- additive annual-detail flag that can surface
losses.irradianceLossDetaileven whenoutput.fullOutputis false
- additive annual-detail flag that can surface
- query params:
blockresults
- body fields:
blockQueryblockQueryIndex- these are compatibility-only selected-block aliases and remain deprecated
- legacy-only
blockQuery+blockQueryIndexstill map to canonicaloutput.blockIndexbehavior and emit deprecation warnings - if canonical
output.blockIndexand legacy block selectors are both present and semantically consistent, the request is accepted and legacy warnings still apply - if canonical
output.blockIndexand legacy block selectors conflict, the API returns422 output.queryis no longer supported and returns422- object-shaped
output.lossBreakdownTimestampsvalues are no longer supported and return422
POST /energymodels?debug_block=...is no longer supported and returns422with guidance to useoutput.blockIndex.POST /energymodels/{id}/run?debug_block=...is also no longer supported and returns422with the same guidance.
summaryfullresults
422 with endpoint-specific guidance.
Example request
Output-shape behavior
- Sync POST shape is controlled by request-body
outputflags. - Detail GET shape is controlled by
include=.... - List GET does not expand shape;
include=summaryis only a compatibility token. output.timeSeries=trueexposes plant-leveltimeSeriesin sync completed responses.output.blockResultscontrolsblockTimeSeriesvisibility and does not rewrite runtime execution scope.output.blockIndexfilters the returnedblockTimeSeriessection only; it does not convert the request into single-block execution.output.lossBreakdownTimestamps=truecan surfaceblockTimeSerieseven whenoutput.blockResultsis omitted or false.blockTimeSerieskeys preserve original zero-based block numbering, including filtered single-block responses.- timestamped loss details live under
blockTimeSeries[<blockIndex>].lossBreakdownwhenoutput.lossBreakdownTimestamps=true. losses.irradianceLossDetailis additive and may appear even whenoutput.fullOutputis false ifoutput.irradianceLossDetail=trueis set.
output.fullTimeSeries=truecan still cause richer stored outputs, but the immediate sync POST response filterstimeSeriesback to the six legacy base keys.
- Async energy-model responses expose only the parent
taskIdintaskDetails. - Fan-out child block tasks and their IDs are internal orchestration details and are not returned on the public API.
Import -> edit -> rerun example
This example shows the intended workflow for an imported PVsyst project template. The sameenergy_model_id is reused across the GET, PUT, and
POST /run steps.
Response contract
Canonical response envelopes and include behavior are documented here:Follow-up calls
- Poll task:
GET /tasks/{taskId}wheretaskId = taskDetails.taskId - Fetch run resource:
GET /energymodels/{energyModelId}
