Energy Model Runs
POST /energymodels accepts an EnergyModelInput payload, queues a run, and
returns 202 Accepted. 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.
For the separate hybrid-1 input contract, use
calculationEngine=hybrid and follow the
PV and Battery Simulations guide.
The PV request and output flags described below apply to the PV input contract.
Endpoint behavior
- Create and saved rerun are asynchronous and return
202when accepted. - The deprecated
asyncquery parameter is accepted as a no-op; either value leaves the request asynchronous. - Poll the parent task, then fetch the completed saved energy-model resource.
- Queued 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 project 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
- POST returns the accepted task envelope. Request-body
outputflags control the result detail calculated and stored for later readback. - Detail GET shape is controlled by
include=.... - List GET does not expand shape;
include=summaryis only a compatibility token. output.timeSeries=truerequests plant-leveltimeSeriesin completed results.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 produce richer stored outputs. Read the detail withinclude=fulltimeseriesto request the expanded public time-series shape.
- 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 external 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}
