> For the complete documentation index, see [llms.txt](https://docs.rootcause.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rootcause.ai/api-and-integrations/rest-api-reference/digital-twins.md).

# Digital Twins

## List digital twins

> Lists digital twins in the workspace. Paginated (limit, cursor). Read from platform MongoDB. Versions are listed under /versions.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"DigitalTwinListEnvelope":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DigitalTwin"}},"pagination":{"type":"object","properties":{"cursor":{"type":"string","description":"Pass back as ?cursor= to fetch the next page"},"hasMore":{"type":"boolean","description":"Whether a further page exists"},"total":{"type":"number","description":"Total matching rows, when the query can count them"}},"required":["hasMore"]}},"required":["data","pagination"]},"DigitalTwin":{"type":"object","properties":{"id":{"type":"string"},"organisationId":{"type":"string"},"workspaceId":{"type":"string"},"name":{"type":"string"},"normalizedName":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/DigitalTwinTypeEnum"},"canonicalInputSchema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaEntryModelSchema"}},{"type":"null"}]},"tags":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"status":{"$ref":"#/components/schemas/StatusTypeEnum","default":"active"},"createdAt":{"type":"string"},"suggestedSimulations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SuggestedSimulationSchema"}},{"type":"null"}]},"suggestionsGeneratedAt":{"type":["string","null"]},"environmentGroups":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/EnvironmentGroupSchema"}},{"type":"null"}]},"autoUpdate":{"anyOf":[{"$ref":"#/components/schemas/AutoUpdateSettingsSchema"},{"type":"null"}]},"maintainedBy":{"type":"array","items":{"type":"object","properties":{"applicationId":{"type":"string"},"version":{"type":"string"},"flowId":{"type":"string"}},"required":["applicationId","version","flowId"]}}},"required":["id","organisationId","workspaceId","name","type"]},"DigitalTwinTypeEnum":{"type":"string","enum":["static","temporal","multi-environment-temporal","multi-environment-static"]},"SchemaEntryModelSchema":{"type":"object","properties":{"field":{"type":"string"},"type":{"$ref":"#/components/schemas/SchemaMainTypeEnum"},"subtype":{"anyOf":[{"$ref":"#/components/schemas/SchemaSubTypeEnum"},{"type":"null"}]},"availableTypes":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaMainTypeEnum"}},{"type":"null"}]},"isIndex":{"type":["boolean","null"]},"categories":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"aliases":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"description":{"type":["string","null"]},"displayWidth":{"type":["number","null"]},"originalFormat":{"type":["string","null"]},"displayFormat":{"type":["string","null"]},"unit":{"type":["string","null"]},"unitModifier":{"type":["number","null"]},"dateOrderAssumed":{"type":["boolean","null"]}},"required":["field","type"]},"SchemaMainTypeEnum":{"type":"string","enum":["None","String","Category","Number","Boolean","DateTime","Array","Unknown"]},"SchemaSubTypeEnum":{"type":"string","enum":["Integer","Float","UnsignedInteger","UnsignedFloat","String","Number","Category","Boolean","DateTime"]},"StatusTypeEnum":{"type":"string","enum":["active","deprecated"]},"SuggestedSimulationSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"scenario":{"$ref":"#/components/schemas/DigitalTwinScenarioSchema"},"createdAt":{"type":"string"}},"required":["id","name","description","scenario","createdAt"]},"DigitalTwinScenarioSchema":{"anyOf":[{"$ref":"#/components/schemas/OptimisationScenarioSchema"},{"$ref":"#/components/schemas/StaticInterventionSpecSchema"},{"$ref":"#/components/schemas/TimeSeriesInterventionSpecSchema"},{"$ref":"#/components/schemas/MultiCounterfactualRequestSchema"},{"$ref":"#/components/schemas/PredictionWithUncertaintyRequestSchema"},{"$ref":"#/components/schemas/ExplanationRequestSchema"},{"$ref":"#/components/schemas/ParentImpactRequestSchema"},{"$ref":"#/components/schemas/ForecastWithUncertaintyRequestSchema"},{"$ref":"#/components/schemas/TemporalExplanationRequestSchema"},{"$ref":"#/components/schemas/TemporalCounterfactualRequestSchema"},{"$ref":"#/components/schemas/TemporalOptimisationScenarioSchema"},{"$ref":"#/components/schemas/PanelForecastRequestSchema"},{"$ref":"#/components/schemas/PanelInterventionSpecSchema"},{"$ref":"#/components/schemas/PanelExplanationRequestSchema"},{"$ref":"#/components/schemas/PanelCounterfactualRequestSchema"},{"$ref":"#/components/schemas/PanelOptimisationScenarioSchema"},{"$ref":"#/components/schemas/PanelParentImpactRequestSchema"},{"$ref":"#/components/schemas/RootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/TemporalRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/PanelRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/StaticPanelRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/AnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/TemporalAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/PanelAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/StaticPanelAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/CausalHealthMonitorRequestSchema"},{"$ref":"#/components/schemas/PanelCausalHealthMonitorRequestSchema"}]},"OptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/OptimisationObjectiveSchema"},"description":"The objectives to optimize"},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Dead field, ignored by the optimizer: subpopulation scoping goes through segmentDefinitions + enableSegmentInterventions. Kept so stored scenarios still parse."},"decisionVars":{"type":"array","items":{"type":"string"},"description":"Variables that can be manipulated during optimization"},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}],"description":"Constraints on variable values and changes"},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}],"description":"Constraints on metric values"},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Segment definitions for segment-aware interventions and per-segment results"},"enableSegmentInterventions":{"type":"boolean","default":false,"description":"Whether to explore segment-specific interventions"},"interventionTypes":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}],"description":"Map of variable name to intervention type: 'set_value', 'relative_percentage', 'relative_absolute', 'set_probability'"},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}],"description":"Configuration for intervention count optimization"}},"required":["type","objectives","decisionVars"]},"OptimisationObjectiveSchema":{"type":"object","properties":{"direction":{"type":"string","enum":["maximise","minimise"],"description":"The direction of the optimization"},"variable":{"type":"string","description":"A descriptive name for this objective/metric (e.g., 'Total Revenue', 'Customer Churn Rate'). Used as a label, not necessarily a variable in the causal graph."},"metricSqlQuery":{"type":"string","description":"SQL query to calculate the metric"},"unit":{"$ref":"#/components/schemas/objectiveUnitReadSchema","description":"Canonical unit id (legacy keys coerced on read). Omit for objectives without a meaningful unit."},"weight":{"type":"number","default":1,"description":"Weight of this objective in multi-objective optimization"},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric"},"target":{"anyOf":[{"$ref":"#/components/schemas/OptimisationTargetSchema"},{"type":"null"}],"description":"Optional target specification (absolute value or percentage improvement)"},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["direction","variable","metricSqlQuery"]},"objectiveUnitReadSchema":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}]},"OptimisationTargetSchema":{"type":"object","properties":{"type":{"type":"string","enum":["absolute","percentage"],"default":"percentage","description":"Whether target is an absolute value or percentage change from baseline"},"value":{"type":["number","null"],"description":"Target value. None means just optimize in the specified direction without a specific target."}}},"ConditionSchema":{"type":"object","properties":{"variable":{"type":"string"},"operator":{"type":"string","enum":["eq","ne","gt","lt","ge","le","in","not_in"]},"value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":["number","string","boolean"]}}]}},"required":["variable","operator","value"]},"VariableConstraintSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable this constraint applies to"},"type":{"type":"string","enum":["range","set","conditional"],"description":"Type of constraint"},"minValue":{"type":["number","null"],"description":"Minimum allowed value (for range type)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value (for range type)"},"allowedValues":{"anyOf":[{"type":"array","items":{"type":["string","number","boolean"]}},{"type":"null"}],"description":"List of allowed values (for set type)"},"maxChangePercent":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Maximum percentage change from baseline allowed"},"conditionalAllowedValues":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionalAllowedValuesSchema"}},{"type":"null"}],"description":"Conditional allowed values based on other variable values (for conditional type)"}},"required":["variable","type"]},"ConditionalAllowedValuesSchema":{"type":"object","properties":{"condition":{"type":"object","properties":{"variable":{"type":"string"},"operator":{"type":"string","enum":["eq","ne","gt","lt","ge","le","in","not_in"]},"value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":["number","string","boolean"]}}]}},"required":["variable","operator","value"],"description":"The condition that must be met for this constraint to apply"},"allowedValues":{"anyOf":[{"type":"array","items":{"type":["string","number","boolean"]}},{"type":"null"}],"description":"Values allowed when condition is met (used for categorical/boolean variables)"},"minValue":{"type":["number","null"],"description":"Minimum allowed value when condition is met (used for numeric variables)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value when condition is met (used for numeric variables)"}},"required":["condition"]},"MetricConstraintSchema":{"type":"object","properties":{"metricName":{"type":"string","description":"Name of the metric being constrained"},"sqlQuery":{"type":"string","description":"SQL query to calculate the metric"},"constraintType":{"type":"string","enum":["min_value","max_value","max_decrease_percent","max_increase_percent","fixed_boolean"],"description":"Type of constraint"},"value":{"type":["number","null"],"description":"Constraint value (absolute for min/max, percentage for percent types)"},"booleanValue":{"type":["boolean","null"],"description":"Boolean value for fixed_boolean constraint type"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Window the constraint is evaluated over on a temporal twin. Null means the whole forecast horizon from the first forecast step."}},"required":["metricName","sqlQuery","constraintType"]},"TemporalMetricSpecSchema":{"type":"object","properties":{"startDate":{"type":["string","null"],"description":"Evaluation start as an ISO date (UTC); the backend resolves it into startTimestampMs"},"endDate":{"type":["string","null"],"description":"Evaluation end as an ISO date (UTC), inclusive"},"startTimestampMs":{"type":["number","null"],"description":"Start timestamp (ms). Without an end the window runs intervalSteps grid steps from here; a start alone is one grid step."},"endTimestampMs":{"type":["number","null"],"description":"End timestamp (ms) inclusive. Windows narrower than one model step widen to one full step."},"intervalSteps":{"type":["number","null"],"description":"Window length in model steps when no end is given, counted from the start (or the first forecast step). Ignored when an end is set."}}},"SegmentDefinitionSchema":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the segment (e.g., 'high_spenders')"},"description":{"type":["string","null"],"description":"User-friendly description of the segment"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"},"description":"List of conditions (ANDed together) defining the segment membership."}},"required":["id","conditions"]},"InterventionCountConfigSchema":{"type":"object","properties":{"maxInterventions":{"anyOf":[{"type":"number","minimum":1},{"type":"null"}],"description":"Maximum number of changes per plan. None means no limit."},"optimizeCount":{"type":"boolean","default":true,"description":"Whether to treat intervention count as an implicit minimization objective"}}},"StaticInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"intervention"},"interventions":{"type":"array","items":{"$ref":"#/components/schemas/InterventionSchema"},"description":"A list of interventions with their respective conditions"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/MetricSchema"},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions for targeted analysis of results."}},"required":["type","interventions","metrics"]},"InterventionSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable to intervene on"},"valueSpec":{"anyOf":[{"$ref":"#/components/schemas/SetValueSpecSchema"},{"$ref":"#/components/schemas/RelativeChangeSpecSchema"},{"$ref":"#/components/schemas/SetProbabilitySpecSchema"},{"$ref":"#/components/schemas/AdjustProbabilitySpecSchema"},{"$ref":"#/components/schemas/SetMembersSpecSchema"},{"$ref":"#/components/schemas/RangeValueSpecSchema"}],"description":"Specification of how to modify the variable."},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Optional conditions defining the subpopulation for intervention."},"detachFormula":{"type":["boolean","null"],"description":"Allow this intervention on a computed value. Its formula is switched off for the run: the variable takes the intervened value instead of being recomputed from its inputs, and its inputs do not move to match."}},"required":["variable","valueSpec"]},"SetValueSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_value"},"value":{"type":["number","string","boolean"],"description":"The specific value to set the variable to (in its original domain)."}},"required":["type","value"]},"RelativeChangeSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"relative_change"},"mode":{"type":"string","enum":["percentage","absolute"],"description":"Whether the change is a percentage or an absolute amount."},"value":{"type":"number","description":"The amount of change (e.g., 10 for +10%, -5 for -5 units)."}},"required":["type","mode","value"]},"SetProbabilitySpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_probability"},"category":{"type":["string","number","boolean"],"description":"The target category value (in its original domain) whose probability will be set."},"probability":{"type":"number","minimum":0,"maximum":1,"description":"The desired probability for the specified category (0.0 to 1.0). Other probabilities will be renormalized."}},"required":["type","category","probability"]},"AdjustProbabilitySpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"adjust_probability"},"category":{"type":["string","number","boolean"],"description":"The target category value whose probability will be adjusted."},"delta":{"type":"number","description":"Percentage-point shift (e.g. 10 means +10pp, -5 means -5pp)."}},"required":["type","category","delta"]},"SetMembersSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_members"},"include":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Members to include in the set"},"exclude":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Members to exclude from the set"},"size":{"type":["number","null"],"description":"Fix the set size"},"replace":{"type":"boolean","description":"If true, zero out all members not in include"}},"required":["type"]},"RangeValueSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"range"},"from":{"type":["number","null"],"description":"First value of the grid, in the variable's original domain. Omit to start at the low end of the observed range."},"to":{"type":["number","null"],"description":"Last value of the grid, in the variable's original domain. Omit to end at the high end of the observed range."},"steps":{"anyOf":[{"type":"integer","minimum":2,"maximum":50},{"type":"null"}],"description":"Number of evenly spaced grid points, inclusive of both bounds (2-50). Omit to let the twin family pick — 20 for a static sweep, fewer for temporal families where one point is a whole forecast."}},"required":["type"]},"MetricSchema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the metric"},"sqlQuery":{"type":"string","description":"The SQL query to calculate the metric"},"unit":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}],"description":"Canonical unit id (legacy keys coerced on read)"},"higherIsBetter":{"type":"boolean","default":true,"description":"Whether a higher value is better for this metric"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Temporal evaluation window for time-aware metrics. Null means the whole forecast horizon from the first forecast step. Ignored by non-temporal twins."},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["name","sqlQuery"]},"TimeSeriesInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_intervention"},"interventions":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"},{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"}}]},"description":"A list of time series interventions or sequences (nested lists) for time series models"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/MetricSchema"},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions for targeted analysis of results."}},"required":["type","interventions","metrics"]},"TimeSeriesInterventionSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable to intervene on"},"valueSpec":{"anyOf":[{"$ref":"#/components/schemas/SetValueSpecSchema"},{"$ref":"#/components/schemas/RelativeChangeSpecSchema"},{"$ref":"#/components/schemas/SetProbabilitySpecSchema"},{"$ref":"#/components/schemas/AdjustProbabilitySpecSchema"},{"$ref":"#/components/schemas/SetMembersSpecSchema"},{"$ref":"#/components/schemas/RangeValueSpecSchema"}],"description":"Specification of how to modify the variable."},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Optional conditions defining the subpopulation for intervention."},"detachFormula":{"type":["boolean","null"],"description":"Allow this intervention on a computed value. Its formula is switched off for the run: the variable takes the intervened value instead of being recomputed from its inputs, and its inputs do not move to match."},"timestamp":{"type":["number","null"],"description":"The timestamp to intervene at (for temporal models)"},"persistent":{"type":["boolean","null"],"description":"If True, intervention persists from timestamp onwards. If False, applies only at that timestamp. Only used for temporal models."},"durationSteps":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Hold the value for this many steps starting at the timestamp, then release. Overrides persistent when set (>1). Only used for temporal models."},"rampSteps":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Number of steps to gradually reach this intervention's value. Within a sequence, ramps from the previous state; on a single intervention, ramps from baseline (relative changes only)."}},"required":["variable","valueSpec"]},"MultiCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"counterfactual"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"List of initial samples"},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}],"description":"Datalake reference replacing inline samples"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/CounterfactualTargetSchema"},"description":"Target variables to change for all samples"},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}],"description":"Constraints defining the search space (applied individually per sample). Variables not mentioned or without a FixedConstraint are implicitly changeable."},"maxChanges":{"type":"number","default":3,"description":"Maximum number of variables to change per sample"}},"required":["type","targets"]},"ScenarioSamplesRefSchema":{"type":"object","properties":{"key":{"type":"string","description":"Datalake object key holding the JSON-encoded samples array"},"format":{"type":"string","enum":["json"],"default":"json"},"rowCount":{"type":"integer","minimum":0,"description":"Number of rows in the referenced blob"}},"required":["key","rowCount"]},"CounterfactualTargetSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The target variable name"},"value":{"description":"The desired value for this target variable"},"matchMode":{"$ref":"#/components/schemas/CounterfactualMatchModeSchema","default":"tolerance","description":"How to decide whether a prediction meets this target: tolerance band, >= target, or <= target."},"toleranceType":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualToleranceTypeSchema"},{"type":"null"}],"description":"When matchMode='tolerance': percentage of |target| or absolute units."},"toleranceValue":{"type":["number","null"],"description":"When matchMode='tolerance': width of the tolerance band (>=0). None/0 means exact match."}},"required":["variable"]},"CounterfactualMatchModeSchema":{"type":"string","enum":["tolerance","orMore","orLess"]},"CounterfactualToleranceTypeSchema":{"type":"string","enum":["percentage","absolute"]},"CounterfactualVariableConstraintSchema":{"anyOf":[{"$ref":"#/components/schemas/RangeConstraintSchema"},{"$ref":"#/components/schemas/SetConstraintSchema"},{"$ref":"#/components/schemas/FixedConstraintSchema"}]},"RangeConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"range"},"minValue":{"type":["number","null"],"description":"Minimum allowed value (inclusive)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value (inclusive)"}},"required":["type"]},"SetConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"set"},"allowedValues":{"type":"array","items":{"type":["string","number","boolean"]},"description":"List of explicitly allowed values."}},"required":["type","allowedValues"]},"FixedConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"fixed"}},"required":["type"]},"PredictionWithUncertaintyRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"prediction"},"sample":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"Samples to predict for"},"sampleRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}],"description":"Datalake reference replacing inline sample"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to predict"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"}},"required":["type","targetVars"]},"ExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"],"description":"The cause variable to explain"},"effectVariable":{"type":["string","null"],"description":"The effect variable to explain"},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"The segments to explain"}},"required":["type"]},"ExplanationModeSchema":{"type":"string","enum":["directional","discovery","impact"]},"ParentImpactRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"parent_impact"},"nodes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Nodes to analyze. None = all non-latent nodes with parents"},"nSamples":{"type":"number","default":500,"description":"Samples per do() contrast (static twins only)"},"horizonOverride":{"type":["number","null"],"description":"Attribution forecast window override (temporal twins only)"}},"required":["type"]},"ForecastWithUncertaintyRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"forecast"},"forecastFrom":{"type":["number","null"],"description":"Timestamp of the forecast start"},"forecastH":{"type":"number","description":"Number of steps to forecast"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to forecast"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"},"originTimestamp":{"type":["number","null"],"description":"Forecast as-of timestamp (ms epoch). Overrides forecastFrom when set."}},"required":["type","forecastH","targetVars"]},"TemporalExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"]},"effectVariable":{"type":["string","null"]},"causeVariables":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Multi-select cause variables for directional mode"},"effectVariables":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Multi-select effect variables for directional mode"},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}]},"forecastHorizonOverride":{"type":["number","null"]}},"required":["type"]},"TemporalCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_counterfactual"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/TemporalCounterfactualTargetSchema"}},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}]},"maxChanges":{"type":"number","default":3},"forecastHorizon":{"type":["number","null"]}},"required":["type","targets"]},"TemporalCounterfactualTargetSchema":{"type":"object","properties":{"variable":{"type":"string"},"value":{},"timestamp":{"type":["number","null"]},"aggregation":{"type":"string","enum":["point","mean","cumulative"],"default":"point"},"targetMode":{"$ref":"#/components/schemas/TargetModeSchema"},"matchMode":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualMatchModeSchema"},{"type":"null"}],"description":"Left unset, each aggregation keeps its own rule: a 10% band for point and mean, at-least for cumulative. A value overrides that."},"toleranceType":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualToleranceTypeSchema"},{"type":"null"}]},"toleranceValue":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]}},"required":["variable"]},"TargetModeSchema":{"type":"string","enum":["absolute","relative_percentage","relative_absolute"],"default":"absolute"},"TemporalOptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/TemporalOptimisationObjectiveSchema"}},"decisionVars":{"type":"array","items":{"type":"string"}},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}]},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}]},"interventionTiming":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TemporalInterventionTimingSchema"}},{"type":"null"}]},"forecastHorizon":{"type":"number"},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}]}},"required":["type","objectives","decisionVars","forecastHorizon"]},"TemporalOptimisationObjectiveSchema":{"type":"object","properties":{"direction":{"type":"string","enum":["maximise","minimise"]},"variable":{"type":"string"},"metricSqlQuery":{"type":"string"},"weight":{"type":"number","default":1},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}]},"discountFactor":{"type":"number","default":1},"conceptId":{"type":["string","null"]},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]}},"required":["direction","variable","metricSqlQuery"]},"TemporalInterventionTimingSchema":{"type":"object","properties":{"variable":{"type":"string"},"earliestTimestamp":{"type":["number","null"]},"latestTimestamp":{"type":["number","null"]},"allowRamping":{"type":"boolean","default":true},"maxRampSteps":{"type":["number","null"]}},"required":["variable"]},"PanelForecastRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_forecast"},"forecastH":{"type":"number","description":"Number of steps to forecast"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to forecast"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments to forecast. None = all environments"},"aggregateMode":{"anyOf":[{"$ref":"#/components/schemas/AggregateModeEnum"},{"type":"null"}],"description":"How to aggregate across environments. Unset defaults to avg at execution — every panel forecast stores an aggregate"},"originTimestamp":{"type":["number","null"],"description":"Forecast as-of timestamp (ms epoch). Overrides forecastFrom per environment."}},"required":["type","forecastH","targetVars"]},"AggregateModeEnum":{"type":"string","enum":["sum","avg","min","max"]},"PanelInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_intervention"},"interventions":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"},{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"}}]},"description":"A list of interventions or sequences"},"metrics":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the metric"},"sqlQuery":{"type":"string","description":"The SQL query to calculate the metric"},"unit":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}],"description":"Canonical unit id (legacy keys coerced on read)"},"higherIsBetter":{"type":"boolean","default":true,"description":"Whether a higher value is better for this metric"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Temporal evaluation spec for time-aware metrics. Null for static panel models."},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["name","sqlQuery"]},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for intervention. None = all environments"}},"required":["type","interventions","metrics"]},"PanelExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"]},"effectVariable":{"type":["string","null"]},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}]},"forecastHorizonOverride":{"type":["number","null"]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for explanation. None = all environments"}},"required":["type"]},"PanelCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_counterfactual"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/TemporalCounterfactualTargetSchema"}},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}]},"maxChanges":{"type":"number","default":3},"forecastHorizon":{"type":["number","null"]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for counterfactual. None = all environments"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"Multi-environment static panels only: baseline states to improve, applied in every environment in scope. Temporal panels solve from the twin's own trajectory and ignore this."}},"required":["type","targets"]},"PanelOptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/TemporalOptimisationObjectiveSchema"}},"decisionVars":{"type":"array","items":{"type":"string"}},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}]},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}]},"interventionTiming":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TemporalInterventionTimingSchema"}},{"type":"null"}]},"forecastHorizon":{"type":["number","null"]},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for optimisation. None = all environments"}},"required":["type","objectives","decisionVars"]},"PanelParentImpactRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_parent_impact"},"nodes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Nodes to analyze. None = all non-latent nodes with parents"},"nSamples":{"type":"number","default":500,"description":"Samples per do() contrast (static twins only)"},"horizonOverride":{"type":["number","null"],"description":"Attribution forecast window override (temporal twins only)"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for parent impact. None = all environments"}},"required":["type"]},"RootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5}},"required":["type","targetVariable"]},"TemporalRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"anomalyTimestep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5}},"required":["type","targetVariable"]},"PanelRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"anomalyTimestep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type","targetVariable"]},"PanelScenarioSamplesRefSchema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"}},"StaticPanelRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"static_panel_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type","targetVariable"]},"AnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true}},"required":["type"]},"TemporalAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRcaTopK":{"type":"integer","minimum":0,"default":1}},"required":["type"]},"PanelAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRcaTopK":{"type":"integer","minimum":0,"default":1},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"StaticPanelAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"static_panel_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"CausalHealthMonitorRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"causal_health_monitor"},"dataSource":{"$ref":"#/components/schemas/ChmDataSourceSchema","default":"observed"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"forecastHorizon":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true}},"required":["type"]},"ChmDataSourceSchema":{"type":"string","enum":["observed","forecast"]},"PanelCausalHealthMonitorRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_causal_health_monitor"},"dataSource":{"$ref":"#/components/schemas/ChmDataSourceSchema","default":"observed"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"forecastHorizon":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"EnvironmentGroupSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"definition":{"$ref":"#/components/schemas/EnvironmentGroupDefinitionSchema"},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"updatedAt":{"type":["string","null"]},"splitColumn":{"type":["string","null"]},"splitValue":{"type":["string","null"]}},"required":["id","name","definition","createdAt"]},"EnvironmentGroupDefinitionSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["columnValues","environments","statFilters"]},"columnValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},{"type":"null"}]},"statFilters":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"},{"type":"null"}]},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}]}},"required":["mode"]},"EnvStatFilterGroupSchema":{"type":"object","properties":{"booleanOperator":{"type":"string","enum":["AND","OR"]},"filters":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterSchema"},{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"}]}}},"required":["booleanOperator","filters"]},"EnvStatFilterSchema":{"type":"object","properties":{"column":{"type":"string"},"comparisonOperator":{"type":"string"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":["string","number","boolean"]}}]},"reduce":{"anyOf":[{"$ref":"#/components/schemas/EnvStatReduceEnum"},{"type":"null"}]}},"required":["column","comparisonOperator","value"]},"EnvStatReduceEnum":{"type":"string","enum":["value","mean","min","max","any"]},"AutoUpdateSettingsSchema":{"type":"object","properties":{"enabled":{"type":"boolean","default":false},"mode":{"type":"string","enum":["assimilate_only","assimilate_or_retrain"],"default":"assimilate_only"}}}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins","summary":"List digital twins","description":"Lists digital twins in the workspace. Paginated (limit, cursor). Read from platform MongoDB. Versions are listed under /versions.","tags":["Digital Twins"],"parameters":[{"in":"query","name":"limit","required":false,"schema":{"description":"Page size (1-1000, default 50).","type":"number","minimum":1,"maximum":1000},"description":"Page size (1-1000, default 50)."},{"in":"query","name":"cursor","required":false,"schema":{"type":"string","description":"Opaque cursor from a previous response's `pagination.cursor`."},"description":"Opaque cursor from a previous response's `pagination.cursor`."},{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DigitalTwinListEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Create digital twin

> Creates a new digital twin and its first version (1.0.0). Body: name, type (static, temporal, multi-environment-temporal, multi-environment-static), optional tags, and the data to model: datasetId (a derived dataset) OR sourceId (model a raw source directly, no dataset required) — at most one of the two. Twin and version records are created in platform MongoDB only; no data-service call until discover, run-pipeline, or train. The response includes versionId for the initial version.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"CreateTwinInput":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string","enum":["static","temporal","multi-environment-temporal","multi-environment-static"],"default":"static"},"tags":{"type":["array","null"],"items":{"type":"string"}},"datasetId":{"type":["string","null"]},"sourceId":{"type":["string","null"]},"selectedTimeColumnName":{"type":["string","null"]},"environmentColumns":{"type":["array","null"],"items":{"type":"string"}},"shardCount":{"type":["integer","null"],"minimum":1}},"required":["name","type"]},"DigitalTwinCreatedEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"organisationId":{"type":"string"},"workspaceId":{"type":"string"},"name":{"type":"string"},"normalizedName":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/DigitalTwinTypeEnum"},"canonicalInputSchema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaEntryModelSchema"}},{"type":"null"}]},"tags":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"status":{"$ref":"#/components/schemas/StatusTypeEnum","default":"active"},"createdAt":{"type":"string"},"suggestedSimulations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SuggestedSimulationSchema"}},{"type":"null"}]},"suggestionsGeneratedAt":{"type":["string","null"]},"environmentGroups":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/EnvironmentGroupSchema"}},{"type":"null"}]},"autoUpdate":{"anyOf":[{"$ref":"#/components/schemas/AutoUpdateSettingsSchema"},{"type":"null"}]},"maintainedBy":{"type":"array","items":{"type":"object","properties":{"applicationId":{"type":"string"},"version":{"type":"string"},"flowId":{"type":"string"}},"required":["applicationId","version","flowId"]}},"versionId":{"type":"string","description":"The version created alongside the twin"}},"required":["id","organisationId","workspaceId","name","type","versionId"]}},"required":["data"]},"DigitalTwinTypeEnum":{"type":"string","enum":["static","temporal","multi-environment-temporal","multi-environment-static"]},"SchemaEntryModelSchema":{"type":"object","properties":{"field":{"type":"string"},"type":{"$ref":"#/components/schemas/SchemaMainTypeEnum"},"subtype":{"anyOf":[{"$ref":"#/components/schemas/SchemaSubTypeEnum"},{"type":"null"}]},"availableTypes":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaMainTypeEnum"}},{"type":"null"}]},"isIndex":{"type":["boolean","null"]},"categories":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"aliases":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"description":{"type":["string","null"]},"displayWidth":{"type":["number","null"]},"originalFormat":{"type":["string","null"]},"displayFormat":{"type":["string","null"]},"unit":{"type":["string","null"]},"unitModifier":{"type":["number","null"]},"dateOrderAssumed":{"type":["boolean","null"]}},"required":["field","type"]},"SchemaMainTypeEnum":{"type":"string","enum":["None","String","Category","Number","Boolean","DateTime","Array","Unknown"]},"SchemaSubTypeEnum":{"type":"string","enum":["Integer","Float","UnsignedInteger","UnsignedFloat","String","Number","Category","Boolean","DateTime"]},"StatusTypeEnum":{"type":"string","enum":["active","deprecated"]},"SuggestedSimulationSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"scenario":{"$ref":"#/components/schemas/DigitalTwinScenarioSchema"},"createdAt":{"type":"string"}},"required":["id","name","description","scenario","createdAt"]},"DigitalTwinScenarioSchema":{"anyOf":[{"$ref":"#/components/schemas/OptimisationScenarioSchema"},{"$ref":"#/components/schemas/StaticInterventionSpecSchema"},{"$ref":"#/components/schemas/TimeSeriesInterventionSpecSchema"},{"$ref":"#/components/schemas/MultiCounterfactualRequestSchema"},{"$ref":"#/components/schemas/PredictionWithUncertaintyRequestSchema"},{"$ref":"#/components/schemas/ExplanationRequestSchema"},{"$ref":"#/components/schemas/ParentImpactRequestSchema"},{"$ref":"#/components/schemas/ForecastWithUncertaintyRequestSchema"},{"$ref":"#/components/schemas/TemporalExplanationRequestSchema"},{"$ref":"#/components/schemas/TemporalCounterfactualRequestSchema"},{"$ref":"#/components/schemas/TemporalOptimisationScenarioSchema"},{"$ref":"#/components/schemas/PanelForecastRequestSchema"},{"$ref":"#/components/schemas/PanelInterventionSpecSchema"},{"$ref":"#/components/schemas/PanelExplanationRequestSchema"},{"$ref":"#/components/schemas/PanelCounterfactualRequestSchema"},{"$ref":"#/components/schemas/PanelOptimisationScenarioSchema"},{"$ref":"#/components/schemas/PanelParentImpactRequestSchema"},{"$ref":"#/components/schemas/RootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/TemporalRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/PanelRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/StaticPanelRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/AnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/TemporalAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/PanelAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/StaticPanelAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/CausalHealthMonitorRequestSchema"},{"$ref":"#/components/schemas/PanelCausalHealthMonitorRequestSchema"}]},"OptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/OptimisationObjectiveSchema"},"description":"The objectives to optimize"},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Dead field, ignored by the optimizer: subpopulation scoping goes through segmentDefinitions + enableSegmentInterventions. Kept so stored scenarios still parse."},"decisionVars":{"type":"array","items":{"type":"string"},"description":"Variables that can be manipulated during optimization"},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}],"description":"Constraints on variable values and changes"},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}],"description":"Constraints on metric values"},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Segment definitions for segment-aware interventions and per-segment results"},"enableSegmentInterventions":{"type":"boolean","default":false,"description":"Whether to explore segment-specific interventions"},"interventionTypes":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}],"description":"Map of variable name to intervention type: 'set_value', 'relative_percentage', 'relative_absolute', 'set_probability'"},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}],"description":"Configuration for intervention count optimization"}},"required":["type","objectives","decisionVars"]},"OptimisationObjectiveSchema":{"type":"object","properties":{"direction":{"type":"string","enum":["maximise","minimise"],"description":"The direction of the optimization"},"variable":{"type":"string","description":"A descriptive name for this objective/metric (e.g., 'Total Revenue', 'Customer Churn Rate'). Used as a label, not necessarily a variable in the causal graph."},"metricSqlQuery":{"type":"string","description":"SQL query to calculate the metric"},"unit":{"$ref":"#/components/schemas/objectiveUnitReadSchema","description":"Canonical unit id (legacy keys coerced on read). Omit for objectives without a meaningful unit."},"weight":{"type":"number","default":1,"description":"Weight of this objective in multi-objective optimization"},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric"},"target":{"anyOf":[{"$ref":"#/components/schemas/OptimisationTargetSchema"},{"type":"null"}],"description":"Optional target specification (absolute value or percentage improvement)"},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["direction","variable","metricSqlQuery"]},"objectiveUnitReadSchema":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}]},"OptimisationTargetSchema":{"type":"object","properties":{"type":{"type":"string","enum":["absolute","percentage"],"default":"percentage","description":"Whether target is an absolute value or percentage change from baseline"},"value":{"type":["number","null"],"description":"Target value. None means just optimize in the specified direction without a specific target."}}},"ConditionSchema":{"type":"object","properties":{"variable":{"type":"string"},"operator":{"type":"string","enum":["eq","ne","gt","lt","ge","le","in","not_in"]},"value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":["number","string","boolean"]}}]}},"required":["variable","operator","value"]},"VariableConstraintSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable this constraint applies to"},"type":{"type":"string","enum":["range","set","conditional"],"description":"Type of constraint"},"minValue":{"type":["number","null"],"description":"Minimum allowed value (for range type)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value (for range type)"},"allowedValues":{"anyOf":[{"type":"array","items":{"type":["string","number","boolean"]}},{"type":"null"}],"description":"List of allowed values (for set type)"},"maxChangePercent":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Maximum percentage change from baseline allowed"},"conditionalAllowedValues":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionalAllowedValuesSchema"}},{"type":"null"}],"description":"Conditional allowed values based on other variable values (for conditional type)"}},"required":["variable","type"]},"ConditionalAllowedValuesSchema":{"type":"object","properties":{"condition":{"type":"object","properties":{"variable":{"type":"string"},"operator":{"type":"string","enum":["eq","ne","gt","lt","ge","le","in","not_in"]},"value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":["number","string","boolean"]}}]}},"required":["variable","operator","value"],"description":"The condition that must be met for this constraint to apply"},"allowedValues":{"anyOf":[{"type":"array","items":{"type":["string","number","boolean"]}},{"type":"null"}],"description":"Values allowed when condition is met (used for categorical/boolean variables)"},"minValue":{"type":["number","null"],"description":"Minimum allowed value when condition is met (used for numeric variables)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value when condition is met (used for numeric variables)"}},"required":["condition"]},"MetricConstraintSchema":{"type":"object","properties":{"metricName":{"type":"string","description":"Name of the metric being constrained"},"sqlQuery":{"type":"string","description":"SQL query to calculate the metric"},"constraintType":{"type":"string","enum":["min_value","max_value","max_decrease_percent","max_increase_percent","fixed_boolean"],"description":"Type of constraint"},"value":{"type":["number","null"],"description":"Constraint value (absolute for min/max, percentage for percent types)"},"booleanValue":{"type":["boolean","null"],"description":"Boolean value for fixed_boolean constraint type"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Window the constraint is evaluated over on a temporal twin. Null means the whole forecast horizon from the first forecast step."}},"required":["metricName","sqlQuery","constraintType"]},"TemporalMetricSpecSchema":{"type":"object","properties":{"startDate":{"type":["string","null"],"description":"Evaluation start as an ISO date (UTC); the backend resolves it into startTimestampMs"},"endDate":{"type":["string","null"],"description":"Evaluation end as an ISO date (UTC), inclusive"},"startTimestampMs":{"type":["number","null"],"description":"Start timestamp (ms). Without an end the window runs intervalSteps grid steps from here; a start alone is one grid step."},"endTimestampMs":{"type":["number","null"],"description":"End timestamp (ms) inclusive. Windows narrower than one model step widen to one full step."},"intervalSteps":{"type":["number","null"],"description":"Window length in model steps when no end is given, counted from the start (or the first forecast step). Ignored when an end is set."}}},"SegmentDefinitionSchema":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the segment (e.g., 'high_spenders')"},"description":{"type":["string","null"],"description":"User-friendly description of the segment"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"},"description":"List of conditions (ANDed together) defining the segment membership."}},"required":["id","conditions"]},"InterventionCountConfigSchema":{"type":"object","properties":{"maxInterventions":{"anyOf":[{"type":"number","minimum":1},{"type":"null"}],"description":"Maximum number of changes per plan. None means no limit."},"optimizeCount":{"type":"boolean","default":true,"description":"Whether to treat intervention count as an implicit minimization objective"}}},"StaticInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"intervention"},"interventions":{"type":"array","items":{"$ref":"#/components/schemas/InterventionSchema"},"description":"A list of interventions with their respective conditions"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/MetricSchema"},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions for targeted analysis of results."}},"required":["type","interventions","metrics"]},"InterventionSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable to intervene on"},"valueSpec":{"anyOf":[{"$ref":"#/components/schemas/SetValueSpecSchema"},{"$ref":"#/components/schemas/RelativeChangeSpecSchema"},{"$ref":"#/components/schemas/SetProbabilitySpecSchema"},{"$ref":"#/components/schemas/AdjustProbabilitySpecSchema"},{"$ref":"#/components/schemas/SetMembersSpecSchema"},{"$ref":"#/components/schemas/RangeValueSpecSchema"}],"description":"Specification of how to modify the variable."},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Optional conditions defining the subpopulation for intervention."},"detachFormula":{"type":["boolean","null"],"description":"Allow this intervention on a computed value. Its formula is switched off for the run: the variable takes the intervened value instead of being recomputed from its inputs, and its inputs do not move to match."}},"required":["variable","valueSpec"]},"SetValueSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_value"},"value":{"type":["number","string","boolean"],"description":"The specific value to set the variable to (in its original domain)."}},"required":["type","value"]},"RelativeChangeSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"relative_change"},"mode":{"type":"string","enum":["percentage","absolute"],"description":"Whether the change is a percentage or an absolute amount."},"value":{"type":"number","description":"The amount of change (e.g., 10 for +10%, -5 for -5 units)."}},"required":["type","mode","value"]},"SetProbabilitySpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_probability"},"category":{"type":["string","number","boolean"],"description":"The target category value (in its original domain) whose probability will be set."},"probability":{"type":"number","minimum":0,"maximum":1,"description":"The desired probability for the specified category (0.0 to 1.0). Other probabilities will be renormalized."}},"required":["type","category","probability"]},"AdjustProbabilitySpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"adjust_probability"},"category":{"type":["string","number","boolean"],"description":"The target category value whose probability will be adjusted."},"delta":{"type":"number","description":"Percentage-point shift (e.g. 10 means +10pp, -5 means -5pp)."}},"required":["type","category","delta"]},"SetMembersSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_members"},"include":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Members to include in the set"},"exclude":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Members to exclude from the set"},"size":{"type":["number","null"],"description":"Fix the set size"},"replace":{"type":"boolean","description":"If true, zero out all members not in include"}},"required":["type"]},"RangeValueSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"range"},"from":{"type":["number","null"],"description":"First value of the grid, in the variable's original domain. Omit to start at the low end of the observed range."},"to":{"type":["number","null"],"description":"Last value of the grid, in the variable's original domain. Omit to end at the high end of the observed range."},"steps":{"anyOf":[{"type":"integer","minimum":2,"maximum":50},{"type":"null"}],"description":"Number of evenly spaced grid points, inclusive of both bounds (2-50). Omit to let the twin family pick — 20 for a static sweep, fewer for temporal families where one point is a whole forecast."}},"required":["type"]},"MetricSchema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the metric"},"sqlQuery":{"type":"string","description":"The SQL query to calculate the metric"},"unit":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}],"description":"Canonical unit id (legacy keys coerced on read)"},"higherIsBetter":{"type":"boolean","default":true,"description":"Whether a higher value is better for this metric"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Temporal evaluation window for time-aware metrics. Null means the whole forecast horizon from the first forecast step. Ignored by non-temporal twins."},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["name","sqlQuery"]},"TimeSeriesInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_intervention"},"interventions":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"},{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"}}]},"description":"A list of time series interventions or sequences (nested lists) for time series models"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/MetricSchema"},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions for targeted analysis of results."}},"required":["type","interventions","metrics"]},"TimeSeriesInterventionSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable to intervene on"},"valueSpec":{"anyOf":[{"$ref":"#/components/schemas/SetValueSpecSchema"},{"$ref":"#/components/schemas/RelativeChangeSpecSchema"},{"$ref":"#/components/schemas/SetProbabilitySpecSchema"},{"$ref":"#/components/schemas/AdjustProbabilitySpecSchema"},{"$ref":"#/components/schemas/SetMembersSpecSchema"},{"$ref":"#/components/schemas/RangeValueSpecSchema"}],"description":"Specification of how to modify the variable."},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Optional conditions defining the subpopulation for intervention."},"detachFormula":{"type":["boolean","null"],"description":"Allow this intervention on a computed value. Its formula is switched off for the run: the variable takes the intervened value instead of being recomputed from its inputs, and its inputs do not move to match."},"timestamp":{"type":["number","null"],"description":"The timestamp to intervene at (for temporal models)"},"persistent":{"type":["boolean","null"],"description":"If True, intervention persists from timestamp onwards. If False, applies only at that timestamp. Only used for temporal models."},"durationSteps":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Hold the value for this many steps starting at the timestamp, then release. Overrides persistent when set (>1). Only used for temporal models."},"rampSteps":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Number of steps to gradually reach this intervention's value. Within a sequence, ramps from the previous state; on a single intervention, ramps from baseline (relative changes only)."}},"required":["variable","valueSpec"]},"MultiCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"counterfactual"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"List of initial samples"},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}],"description":"Datalake reference replacing inline samples"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/CounterfactualTargetSchema"},"description":"Target variables to change for all samples"},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}],"description":"Constraints defining the search space (applied individually per sample). Variables not mentioned or without a FixedConstraint are implicitly changeable."},"maxChanges":{"type":"number","default":3,"description":"Maximum number of variables to change per sample"}},"required":["type","targets"]},"ScenarioSamplesRefSchema":{"type":"object","properties":{"key":{"type":"string","description":"Datalake object key holding the JSON-encoded samples array"},"format":{"type":"string","enum":["json"],"default":"json"},"rowCount":{"type":"integer","minimum":0,"description":"Number of rows in the referenced blob"}},"required":["key","rowCount"]},"CounterfactualTargetSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The target variable name"},"value":{"description":"The desired value for this target variable"},"matchMode":{"$ref":"#/components/schemas/CounterfactualMatchModeSchema","default":"tolerance","description":"How to decide whether a prediction meets this target: tolerance band, >= target, or <= target."},"toleranceType":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualToleranceTypeSchema"},{"type":"null"}],"description":"When matchMode='tolerance': percentage of |target| or absolute units."},"toleranceValue":{"type":["number","null"],"description":"When matchMode='tolerance': width of the tolerance band (>=0). None/0 means exact match."}},"required":["variable"]},"CounterfactualMatchModeSchema":{"type":"string","enum":["tolerance","orMore","orLess"]},"CounterfactualToleranceTypeSchema":{"type":"string","enum":["percentage","absolute"]},"CounterfactualVariableConstraintSchema":{"anyOf":[{"$ref":"#/components/schemas/RangeConstraintSchema"},{"$ref":"#/components/schemas/SetConstraintSchema"},{"$ref":"#/components/schemas/FixedConstraintSchema"}]},"RangeConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"range"},"minValue":{"type":["number","null"],"description":"Minimum allowed value (inclusive)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value (inclusive)"}},"required":["type"]},"SetConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"set"},"allowedValues":{"type":"array","items":{"type":["string","number","boolean"]},"description":"List of explicitly allowed values."}},"required":["type","allowedValues"]},"FixedConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"fixed"}},"required":["type"]},"PredictionWithUncertaintyRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"prediction"},"sample":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"Samples to predict for"},"sampleRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}],"description":"Datalake reference replacing inline sample"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to predict"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"}},"required":["type","targetVars"]},"ExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"],"description":"The cause variable to explain"},"effectVariable":{"type":["string","null"],"description":"The effect variable to explain"},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"The segments to explain"}},"required":["type"]},"ExplanationModeSchema":{"type":"string","enum":["directional","discovery","impact"]},"ParentImpactRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"parent_impact"},"nodes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Nodes to analyze. None = all non-latent nodes with parents"},"nSamples":{"type":"number","default":500,"description":"Samples per do() contrast (static twins only)"},"horizonOverride":{"type":["number","null"],"description":"Attribution forecast window override (temporal twins only)"}},"required":["type"]},"ForecastWithUncertaintyRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"forecast"},"forecastFrom":{"type":["number","null"],"description":"Timestamp of the forecast start"},"forecastH":{"type":"number","description":"Number of steps to forecast"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to forecast"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"},"originTimestamp":{"type":["number","null"],"description":"Forecast as-of timestamp (ms epoch). Overrides forecastFrom when set."}},"required":["type","forecastH","targetVars"]},"TemporalExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"]},"effectVariable":{"type":["string","null"]},"causeVariables":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Multi-select cause variables for directional mode"},"effectVariables":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Multi-select effect variables for directional mode"},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}]},"forecastHorizonOverride":{"type":["number","null"]}},"required":["type"]},"TemporalCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_counterfactual"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/TemporalCounterfactualTargetSchema"}},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}]},"maxChanges":{"type":"number","default":3},"forecastHorizon":{"type":["number","null"]}},"required":["type","targets"]},"TemporalCounterfactualTargetSchema":{"type":"object","properties":{"variable":{"type":"string"},"value":{},"timestamp":{"type":["number","null"]},"aggregation":{"type":"string","enum":["point","mean","cumulative"],"default":"point"},"targetMode":{"$ref":"#/components/schemas/TargetModeSchema"},"matchMode":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualMatchModeSchema"},{"type":"null"}],"description":"Left unset, each aggregation keeps its own rule: a 10% band for point and mean, at-least for cumulative. A value overrides that."},"toleranceType":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualToleranceTypeSchema"},{"type":"null"}]},"toleranceValue":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]}},"required":["variable"]},"TargetModeSchema":{"type":"string","enum":["absolute","relative_percentage","relative_absolute"],"default":"absolute"},"TemporalOptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/TemporalOptimisationObjectiveSchema"}},"decisionVars":{"type":"array","items":{"type":"string"}},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}]},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}]},"interventionTiming":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TemporalInterventionTimingSchema"}},{"type":"null"}]},"forecastHorizon":{"type":"number"},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}]}},"required":["type","objectives","decisionVars","forecastHorizon"]},"TemporalOptimisationObjectiveSchema":{"type":"object","properties":{"direction":{"type":"string","enum":["maximise","minimise"]},"variable":{"type":"string"},"metricSqlQuery":{"type":"string"},"weight":{"type":"number","default":1},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}]},"discountFactor":{"type":"number","default":1},"conceptId":{"type":["string","null"]},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]}},"required":["direction","variable","metricSqlQuery"]},"TemporalInterventionTimingSchema":{"type":"object","properties":{"variable":{"type":"string"},"earliestTimestamp":{"type":["number","null"]},"latestTimestamp":{"type":["number","null"]},"allowRamping":{"type":"boolean","default":true},"maxRampSteps":{"type":["number","null"]}},"required":["variable"]},"PanelForecastRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_forecast"},"forecastH":{"type":"number","description":"Number of steps to forecast"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to forecast"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments to forecast. None = all environments"},"aggregateMode":{"anyOf":[{"$ref":"#/components/schemas/AggregateModeEnum"},{"type":"null"}],"description":"How to aggregate across environments. Unset defaults to avg at execution — every panel forecast stores an aggregate"},"originTimestamp":{"type":["number","null"],"description":"Forecast as-of timestamp (ms epoch). Overrides forecastFrom per environment."}},"required":["type","forecastH","targetVars"]},"AggregateModeEnum":{"type":"string","enum":["sum","avg","min","max"]},"PanelInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_intervention"},"interventions":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"},{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"}}]},"description":"A list of interventions or sequences"},"metrics":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the metric"},"sqlQuery":{"type":"string","description":"The SQL query to calculate the metric"},"unit":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}],"description":"Canonical unit id (legacy keys coerced on read)"},"higherIsBetter":{"type":"boolean","default":true,"description":"Whether a higher value is better for this metric"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Temporal evaluation spec for time-aware metrics. Null for static panel models."},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["name","sqlQuery"]},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for intervention. None = all environments"}},"required":["type","interventions","metrics"]},"PanelExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"]},"effectVariable":{"type":["string","null"]},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}]},"forecastHorizonOverride":{"type":["number","null"]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for explanation. None = all environments"}},"required":["type"]},"PanelCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_counterfactual"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/TemporalCounterfactualTargetSchema"}},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}]},"maxChanges":{"type":"number","default":3},"forecastHorizon":{"type":["number","null"]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for counterfactual. None = all environments"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"Multi-environment static panels only: baseline states to improve, applied in every environment in scope. Temporal panels solve from the twin's own trajectory and ignore this."}},"required":["type","targets"]},"PanelOptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/TemporalOptimisationObjectiveSchema"}},"decisionVars":{"type":"array","items":{"type":"string"}},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}]},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}]},"interventionTiming":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TemporalInterventionTimingSchema"}},{"type":"null"}]},"forecastHorizon":{"type":["number","null"]},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for optimisation. None = all environments"}},"required":["type","objectives","decisionVars"]},"PanelParentImpactRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_parent_impact"},"nodes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Nodes to analyze. None = all non-latent nodes with parents"},"nSamples":{"type":"number","default":500,"description":"Samples per do() contrast (static twins only)"},"horizonOverride":{"type":["number","null"],"description":"Attribution forecast window override (temporal twins only)"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for parent impact. None = all environments"}},"required":["type"]},"RootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5}},"required":["type","targetVariable"]},"TemporalRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"anomalyTimestep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5}},"required":["type","targetVariable"]},"PanelRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"anomalyTimestep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type","targetVariable"]},"PanelScenarioSamplesRefSchema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"}},"StaticPanelRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"static_panel_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type","targetVariable"]},"AnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true}},"required":["type"]},"TemporalAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRcaTopK":{"type":"integer","minimum":0,"default":1}},"required":["type"]},"PanelAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRcaTopK":{"type":"integer","minimum":0,"default":1},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"StaticPanelAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"static_panel_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"CausalHealthMonitorRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"causal_health_monitor"},"dataSource":{"$ref":"#/components/schemas/ChmDataSourceSchema","default":"observed"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"forecastHorizon":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true}},"required":["type"]},"ChmDataSourceSchema":{"type":"string","enum":["observed","forecast"]},"PanelCausalHealthMonitorRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_causal_health_monitor"},"dataSource":{"$ref":"#/components/schemas/ChmDataSourceSchema","default":"observed"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"forecastHorizon":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"EnvironmentGroupSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"definition":{"$ref":"#/components/schemas/EnvironmentGroupDefinitionSchema"},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"updatedAt":{"type":["string","null"]},"splitColumn":{"type":["string","null"]},"splitValue":{"type":["string","null"]}},"required":["id","name","definition","createdAt"]},"EnvironmentGroupDefinitionSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["columnValues","environments","statFilters"]},"columnValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},{"type":"null"}]},"statFilters":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"},{"type":"null"}]},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}]}},"required":["mode"]},"EnvStatFilterGroupSchema":{"type":"object","properties":{"booleanOperator":{"type":"string","enum":["AND","OR"]},"filters":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterSchema"},{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"}]}}},"required":["booleanOperator","filters"]},"EnvStatFilterSchema":{"type":"object","properties":{"column":{"type":"string"},"comparisonOperator":{"type":"string"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":["string","number","boolean"]}}]},"reduce":{"anyOf":[{"$ref":"#/components/schemas/EnvStatReduceEnum"},{"type":"null"}]}},"required":["column","comparisonOperator","value"]},"EnvStatReduceEnum":{"type":"string","enum":["value","mean","min","max","any"]},"AutoUpdateSettingsSchema":{"type":"object","properties":{"enabled":{"type":"boolean","default":false},"mode":{"type":"string","enum":["assimilate_only","assimilate_or_retrain"],"default":"assimilate_only"}}}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins","summary":"Create digital twin","description":"Creates a new digital twin and its first version (1.0.0). Body: name, type (static, temporal, multi-environment-temporal, multi-environment-static), optional tags, and the data to model: datasetId (a derived dataset) OR sourceId (model a raw source directly, no dataset required) — at most one of the two. Twin and version records are created in platform MongoDB only; no data-service call until discover, run-pipeline, or train. The response includes versionId for the initial version.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTwinInput"}}}},"responses":{"201":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DigitalTwinCreatedEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get digital twin

> Returns the digital twin by id from platform MongoDB. Must belong to the workspace. Includes canonicalInputSchema, suggestedSimulations.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"DigitalTwinEnvelope":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/DigitalTwin"}},"required":["data"]},"DigitalTwin":{"type":"object","properties":{"id":{"type":"string"},"organisationId":{"type":"string"},"workspaceId":{"type":"string"},"name":{"type":"string"},"normalizedName":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/DigitalTwinTypeEnum"},"canonicalInputSchema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaEntryModelSchema"}},{"type":"null"}]},"tags":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"status":{"$ref":"#/components/schemas/StatusTypeEnum","default":"active"},"createdAt":{"type":"string"},"suggestedSimulations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SuggestedSimulationSchema"}},{"type":"null"}]},"suggestionsGeneratedAt":{"type":["string","null"]},"environmentGroups":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/EnvironmentGroupSchema"}},{"type":"null"}]},"autoUpdate":{"anyOf":[{"$ref":"#/components/schemas/AutoUpdateSettingsSchema"},{"type":"null"}]},"maintainedBy":{"type":"array","items":{"type":"object","properties":{"applicationId":{"type":"string"},"version":{"type":"string"},"flowId":{"type":"string"}},"required":["applicationId","version","flowId"]}}},"required":["id","organisationId","workspaceId","name","type"]},"DigitalTwinTypeEnum":{"type":"string","enum":["static","temporal","multi-environment-temporal","multi-environment-static"]},"SchemaEntryModelSchema":{"type":"object","properties":{"field":{"type":"string"},"type":{"$ref":"#/components/schemas/SchemaMainTypeEnum"},"subtype":{"anyOf":[{"$ref":"#/components/schemas/SchemaSubTypeEnum"},{"type":"null"}]},"availableTypes":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaMainTypeEnum"}},{"type":"null"}]},"isIndex":{"type":["boolean","null"]},"categories":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"aliases":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"description":{"type":["string","null"]},"displayWidth":{"type":["number","null"]},"originalFormat":{"type":["string","null"]},"displayFormat":{"type":["string","null"]},"unit":{"type":["string","null"]},"unitModifier":{"type":["number","null"]},"dateOrderAssumed":{"type":["boolean","null"]}},"required":["field","type"]},"SchemaMainTypeEnum":{"type":"string","enum":["None","String","Category","Number","Boolean","DateTime","Array","Unknown"]},"SchemaSubTypeEnum":{"type":"string","enum":["Integer","Float","UnsignedInteger","UnsignedFloat","String","Number","Category","Boolean","DateTime"]},"StatusTypeEnum":{"type":"string","enum":["active","deprecated"]},"SuggestedSimulationSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"scenario":{"$ref":"#/components/schemas/DigitalTwinScenarioSchema"},"createdAt":{"type":"string"}},"required":["id","name","description","scenario","createdAt"]},"DigitalTwinScenarioSchema":{"anyOf":[{"$ref":"#/components/schemas/OptimisationScenarioSchema"},{"$ref":"#/components/schemas/StaticInterventionSpecSchema"},{"$ref":"#/components/schemas/TimeSeriesInterventionSpecSchema"},{"$ref":"#/components/schemas/MultiCounterfactualRequestSchema"},{"$ref":"#/components/schemas/PredictionWithUncertaintyRequestSchema"},{"$ref":"#/components/schemas/ExplanationRequestSchema"},{"$ref":"#/components/schemas/ParentImpactRequestSchema"},{"$ref":"#/components/schemas/ForecastWithUncertaintyRequestSchema"},{"$ref":"#/components/schemas/TemporalExplanationRequestSchema"},{"$ref":"#/components/schemas/TemporalCounterfactualRequestSchema"},{"$ref":"#/components/schemas/TemporalOptimisationScenarioSchema"},{"$ref":"#/components/schemas/PanelForecastRequestSchema"},{"$ref":"#/components/schemas/PanelInterventionSpecSchema"},{"$ref":"#/components/schemas/PanelExplanationRequestSchema"},{"$ref":"#/components/schemas/PanelCounterfactualRequestSchema"},{"$ref":"#/components/schemas/PanelOptimisationScenarioSchema"},{"$ref":"#/components/schemas/PanelParentImpactRequestSchema"},{"$ref":"#/components/schemas/RootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/TemporalRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/PanelRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/StaticPanelRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/AnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/TemporalAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/PanelAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/StaticPanelAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/CausalHealthMonitorRequestSchema"},{"$ref":"#/components/schemas/PanelCausalHealthMonitorRequestSchema"}]},"OptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/OptimisationObjectiveSchema"},"description":"The objectives to optimize"},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Dead field, ignored by the optimizer: subpopulation scoping goes through segmentDefinitions + enableSegmentInterventions. Kept so stored scenarios still parse."},"decisionVars":{"type":"array","items":{"type":"string"},"description":"Variables that can be manipulated during optimization"},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}],"description":"Constraints on variable values and changes"},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}],"description":"Constraints on metric values"},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Segment definitions for segment-aware interventions and per-segment results"},"enableSegmentInterventions":{"type":"boolean","default":false,"description":"Whether to explore segment-specific interventions"},"interventionTypes":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}],"description":"Map of variable name to intervention type: 'set_value', 'relative_percentage', 'relative_absolute', 'set_probability'"},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}],"description":"Configuration for intervention count optimization"}},"required":["type","objectives","decisionVars"]},"OptimisationObjectiveSchema":{"type":"object","properties":{"direction":{"type":"string","enum":["maximise","minimise"],"description":"The direction of the optimization"},"variable":{"type":"string","description":"A descriptive name for this objective/metric (e.g., 'Total Revenue', 'Customer Churn Rate'). Used as a label, not necessarily a variable in the causal graph."},"metricSqlQuery":{"type":"string","description":"SQL query to calculate the metric"},"unit":{"$ref":"#/components/schemas/objectiveUnitReadSchema","description":"Canonical unit id (legacy keys coerced on read). Omit for objectives without a meaningful unit."},"weight":{"type":"number","default":1,"description":"Weight of this objective in multi-objective optimization"},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric"},"target":{"anyOf":[{"$ref":"#/components/schemas/OptimisationTargetSchema"},{"type":"null"}],"description":"Optional target specification (absolute value or percentage improvement)"},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["direction","variable","metricSqlQuery"]},"objectiveUnitReadSchema":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}]},"OptimisationTargetSchema":{"type":"object","properties":{"type":{"type":"string","enum":["absolute","percentage"],"default":"percentage","description":"Whether target is an absolute value or percentage change from baseline"},"value":{"type":["number","null"],"description":"Target value. None means just optimize in the specified direction without a specific target."}}},"ConditionSchema":{"type":"object","properties":{"variable":{"type":"string"},"operator":{"type":"string","enum":["eq","ne","gt","lt","ge","le","in","not_in"]},"value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":["number","string","boolean"]}}]}},"required":["variable","operator","value"]},"VariableConstraintSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable this constraint applies to"},"type":{"type":"string","enum":["range","set","conditional"],"description":"Type of constraint"},"minValue":{"type":["number","null"],"description":"Minimum allowed value (for range type)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value (for range type)"},"allowedValues":{"anyOf":[{"type":"array","items":{"type":["string","number","boolean"]}},{"type":"null"}],"description":"List of allowed values (for set type)"},"maxChangePercent":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Maximum percentage change from baseline allowed"},"conditionalAllowedValues":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionalAllowedValuesSchema"}},{"type":"null"}],"description":"Conditional allowed values based on other variable values (for conditional type)"}},"required":["variable","type"]},"ConditionalAllowedValuesSchema":{"type":"object","properties":{"condition":{"type":"object","properties":{"variable":{"type":"string"},"operator":{"type":"string","enum":["eq","ne","gt","lt","ge","le","in","not_in"]},"value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":["number","string","boolean"]}}]}},"required":["variable","operator","value"],"description":"The condition that must be met for this constraint to apply"},"allowedValues":{"anyOf":[{"type":"array","items":{"type":["string","number","boolean"]}},{"type":"null"}],"description":"Values allowed when condition is met (used for categorical/boolean variables)"},"minValue":{"type":["number","null"],"description":"Minimum allowed value when condition is met (used for numeric variables)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value when condition is met (used for numeric variables)"}},"required":["condition"]},"MetricConstraintSchema":{"type":"object","properties":{"metricName":{"type":"string","description":"Name of the metric being constrained"},"sqlQuery":{"type":"string","description":"SQL query to calculate the metric"},"constraintType":{"type":"string","enum":["min_value","max_value","max_decrease_percent","max_increase_percent","fixed_boolean"],"description":"Type of constraint"},"value":{"type":["number","null"],"description":"Constraint value (absolute for min/max, percentage for percent types)"},"booleanValue":{"type":["boolean","null"],"description":"Boolean value for fixed_boolean constraint type"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Window the constraint is evaluated over on a temporal twin. Null means the whole forecast horizon from the first forecast step."}},"required":["metricName","sqlQuery","constraintType"]},"TemporalMetricSpecSchema":{"type":"object","properties":{"startDate":{"type":["string","null"],"description":"Evaluation start as an ISO date (UTC); the backend resolves it into startTimestampMs"},"endDate":{"type":["string","null"],"description":"Evaluation end as an ISO date (UTC), inclusive"},"startTimestampMs":{"type":["number","null"],"description":"Start timestamp (ms). Without an end the window runs intervalSteps grid steps from here; a start alone is one grid step."},"endTimestampMs":{"type":["number","null"],"description":"End timestamp (ms) inclusive. Windows narrower than one model step widen to one full step."},"intervalSteps":{"type":["number","null"],"description":"Window length in model steps when no end is given, counted from the start (or the first forecast step). Ignored when an end is set."}}},"SegmentDefinitionSchema":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the segment (e.g., 'high_spenders')"},"description":{"type":["string","null"],"description":"User-friendly description of the segment"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"},"description":"List of conditions (ANDed together) defining the segment membership."}},"required":["id","conditions"]},"InterventionCountConfigSchema":{"type":"object","properties":{"maxInterventions":{"anyOf":[{"type":"number","minimum":1},{"type":"null"}],"description":"Maximum number of changes per plan. None means no limit."},"optimizeCount":{"type":"boolean","default":true,"description":"Whether to treat intervention count as an implicit minimization objective"}}},"StaticInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"intervention"},"interventions":{"type":"array","items":{"$ref":"#/components/schemas/InterventionSchema"},"description":"A list of interventions with their respective conditions"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/MetricSchema"},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions for targeted analysis of results."}},"required":["type","interventions","metrics"]},"InterventionSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable to intervene on"},"valueSpec":{"anyOf":[{"$ref":"#/components/schemas/SetValueSpecSchema"},{"$ref":"#/components/schemas/RelativeChangeSpecSchema"},{"$ref":"#/components/schemas/SetProbabilitySpecSchema"},{"$ref":"#/components/schemas/AdjustProbabilitySpecSchema"},{"$ref":"#/components/schemas/SetMembersSpecSchema"},{"$ref":"#/components/schemas/RangeValueSpecSchema"}],"description":"Specification of how to modify the variable."},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Optional conditions defining the subpopulation for intervention."},"detachFormula":{"type":["boolean","null"],"description":"Allow this intervention on a computed value. Its formula is switched off for the run: the variable takes the intervened value instead of being recomputed from its inputs, and its inputs do not move to match."}},"required":["variable","valueSpec"]},"SetValueSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_value"},"value":{"type":["number","string","boolean"],"description":"The specific value to set the variable to (in its original domain)."}},"required":["type","value"]},"RelativeChangeSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"relative_change"},"mode":{"type":"string","enum":["percentage","absolute"],"description":"Whether the change is a percentage or an absolute amount."},"value":{"type":"number","description":"The amount of change (e.g., 10 for +10%, -5 for -5 units)."}},"required":["type","mode","value"]},"SetProbabilitySpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_probability"},"category":{"type":["string","number","boolean"],"description":"The target category value (in its original domain) whose probability will be set."},"probability":{"type":"number","minimum":0,"maximum":1,"description":"The desired probability for the specified category (0.0 to 1.0). Other probabilities will be renormalized."}},"required":["type","category","probability"]},"AdjustProbabilitySpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"adjust_probability"},"category":{"type":["string","number","boolean"],"description":"The target category value whose probability will be adjusted."},"delta":{"type":"number","description":"Percentage-point shift (e.g. 10 means +10pp, -5 means -5pp)."}},"required":["type","category","delta"]},"SetMembersSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_members"},"include":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Members to include in the set"},"exclude":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Members to exclude from the set"},"size":{"type":["number","null"],"description":"Fix the set size"},"replace":{"type":"boolean","description":"If true, zero out all members not in include"}},"required":["type"]},"RangeValueSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"range"},"from":{"type":["number","null"],"description":"First value of the grid, in the variable's original domain. Omit to start at the low end of the observed range."},"to":{"type":["number","null"],"description":"Last value of the grid, in the variable's original domain. Omit to end at the high end of the observed range."},"steps":{"anyOf":[{"type":"integer","minimum":2,"maximum":50},{"type":"null"}],"description":"Number of evenly spaced grid points, inclusive of both bounds (2-50). Omit to let the twin family pick — 20 for a static sweep, fewer for temporal families where one point is a whole forecast."}},"required":["type"]},"MetricSchema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the metric"},"sqlQuery":{"type":"string","description":"The SQL query to calculate the metric"},"unit":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}],"description":"Canonical unit id (legacy keys coerced on read)"},"higherIsBetter":{"type":"boolean","default":true,"description":"Whether a higher value is better for this metric"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Temporal evaluation window for time-aware metrics. Null means the whole forecast horizon from the first forecast step. Ignored by non-temporal twins."},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["name","sqlQuery"]},"TimeSeriesInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_intervention"},"interventions":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"},{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"}}]},"description":"A list of time series interventions or sequences (nested lists) for time series models"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/MetricSchema"},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions for targeted analysis of results."}},"required":["type","interventions","metrics"]},"TimeSeriesInterventionSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable to intervene on"},"valueSpec":{"anyOf":[{"$ref":"#/components/schemas/SetValueSpecSchema"},{"$ref":"#/components/schemas/RelativeChangeSpecSchema"},{"$ref":"#/components/schemas/SetProbabilitySpecSchema"},{"$ref":"#/components/schemas/AdjustProbabilitySpecSchema"},{"$ref":"#/components/schemas/SetMembersSpecSchema"},{"$ref":"#/components/schemas/RangeValueSpecSchema"}],"description":"Specification of how to modify the variable."},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Optional conditions defining the subpopulation for intervention."},"detachFormula":{"type":["boolean","null"],"description":"Allow this intervention on a computed value. Its formula is switched off for the run: the variable takes the intervened value instead of being recomputed from its inputs, and its inputs do not move to match."},"timestamp":{"type":["number","null"],"description":"The timestamp to intervene at (for temporal models)"},"persistent":{"type":["boolean","null"],"description":"If True, intervention persists from timestamp onwards. If False, applies only at that timestamp. Only used for temporal models."},"durationSteps":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Hold the value for this many steps starting at the timestamp, then release. Overrides persistent when set (>1). Only used for temporal models."},"rampSteps":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Number of steps to gradually reach this intervention's value. Within a sequence, ramps from the previous state; on a single intervention, ramps from baseline (relative changes only)."}},"required":["variable","valueSpec"]},"MultiCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"counterfactual"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"List of initial samples"},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}],"description":"Datalake reference replacing inline samples"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/CounterfactualTargetSchema"},"description":"Target variables to change for all samples"},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}],"description":"Constraints defining the search space (applied individually per sample). Variables not mentioned or without a FixedConstraint are implicitly changeable."},"maxChanges":{"type":"number","default":3,"description":"Maximum number of variables to change per sample"}},"required":["type","targets"]},"ScenarioSamplesRefSchema":{"type":"object","properties":{"key":{"type":"string","description":"Datalake object key holding the JSON-encoded samples array"},"format":{"type":"string","enum":["json"],"default":"json"},"rowCount":{"type":"integer","minimum":0,"description":"Number of rows in the referenced blob"}},"required":["key","rowCount"]},"CounterfactualTargetSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The target variable name"},"value":{"description":"The desired value for this target variable"},"matchMode":{"$ref":"#/components/schemas/CounterfactualMatchModeSchema","default":"tolerance","description":"How to decide whether a prediction meets this target: tolerance band, >= target, or <= target."},"toleranceType":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualToleranceTypeSchema"},{"type":"null"}],"description":"When matchMode='tolerance': percentage of |target| or absolute units."},"toleranceValue":{"type":["number","null"],"description":"When matchMode='tolerance': width of the tolerance band (>=0). None/0 means exact match."}},"required":["variable"]},"CounterfactualMatchModeSchema":{"type":"string","enum":["tolerance","orMore","orLess"]},"CounterfactualToleranceTypeSchema":{"type":"string","enum":["percentage","absolute"]},"CounterfactualVariableConstraintSchema":{"anyOf":[{"$ref":"#/components/schemas/RangeConstraintSchema"},{"$ref":"#/components/schemas/SetConstraintSchema"},{"$ref":"#/components/schemas/FixedConstraintSchema"}]},"RangeConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"range"},"minValue":{"type":["number","null"],"description":"Minimum allowed value (inclusive)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value (inclusive)"}},"required":["type"]},"SetConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"set"},"allowedValues":{"type":"array","items":{"type":["string","number","boolean"]},"description":"List of explicitly allowed values."}},"required":["type","allowedValues"]},"FixedConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"fixed"}},"required":["type"]},"PredictionWithUncertaintyRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"prediction"},"sample":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"Samples to predict for"},"sampleRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}],"description":"Datalake reference replacing inline sample"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to predict"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"}},"required":["type","targetVars"]},"ExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"],"description":"The cause variable to explain"},"effectVariable":{"type":["string","null"],"description":"The effect variable to explain"},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"The segments to explain"}},"required":["type"]},"ExplanationModeSchema":{"type":"string","enum":["directional","discovery","impact"]},"ParentImpactRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"parent_impact"},"nodes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Nodes to analyze. None = all non-latent nodes with parents"},"nSamples":{"type":"number","default":500,"description":"Samples per do() contrast (static twins only)"},"horizonOverride":{"type":["number","null"],"description":"Attribution forecast window override (temporal twins only)"}},"required":["type"]},"ForecastWithUncertaintyRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"forecast"},"forecastFrom":{"type":["number","null"],"description":"Timestamp of the forecast start"},"forecastH":{"type":"number","description":"Number of steps to forecast"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to forecast"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"},"originTimestamp":{"type":["number","null"],"description":"Forecast as-of timestamp (ms epoch). Overrides forecastFrom when set."}},"required":["type","forecastH","targetVars"]},"TemporalExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"]},"effectVariable":{"type":["string","null"]},"causeVariables":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Multi-select cause variables for directional mode"},"effectVariables":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Multi-select effect variables for directional mode"},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}]},"forecastHorizonOverride":{"type":["number","null"]}},"required":["type"]},"TemporalCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_counterfactual"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/TemporalCounterfactualTargetSchema"}},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}]},"maxChanges":{"type":"number","default":3},"forecastHorizon":{"type":["number","null"]}},"required":["type","targets"]},"TemporalCounterfactualTargetSchema":{"type":"object","properties":{"variable":{"type":"string"},"value":{},"timestamp":{"type":["number","null"]},"aggregation":{"type":"string","enum":["point","mean","cumulative"],"default":"point"},"targetMode":{"$ref":"#/components/schemas/TargetModeSchema"},"matchMode":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualMatchModeSchema"},{"type":"null"}],"description":"Left unset, each aggregation keeps its own rule: a 10% band for point and mean, at-least for cumulative. A value overrides that."},"toleranceType":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualToleranceTypeSchema"},{"type":"null"}]},"toleranceValue":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]}},"required":["variable"]},"TargetModeSchema":{"type":"string","enum":["absolute","relative_percentage","relative_absolute"],"default":"absolute"},"TemporalOptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/TemporalOptimisationObjectiveSchema"}},"decisionVars":{"type":"array","items":{"type":"string"}},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}]},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}]},"interventionTiming":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TemporalInterventionTimingSchema"}},{"type":"null"}]},"forecastHorizon":{"type":"number"},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}]}},"required":["type","objectives","decisionVars","forecastHorizon"]},"TemporalOptimisationObjectiveSchema":{"type":"object","properties":{"direction":{"type":"string","enum":["maximise","minimise"]},"variable":{"type":"string"},"metricSqlQuery":{"type":"string"},"weight":{"type":"number","default":1},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}]},"discountFactor":{"type":"number","default":1},"conceptId":{"type":["string","null"]},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]}},"required":["direction","variable","metricSqlQuery"]},"TemporalInterventionTimingSchema":{"type":"object","properties":{"variable":{"type":"string"},"earliestTimestamp":{"type":["number","null"]},"latestTimestamp":{"type":["number","null"]},"allowRamping":{"type":"boolean","default":true},"maxRampSteps":{"type":["number","null"]}},"required":["variable"]},"PanelForecastRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_forecast"},"forecastH":{"type":"number","description":"Number of steps to forecast"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to forecast"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments to forecast. None = all environments"},"aggregateMode":{"anyOf":[{"$ref":"#/components/schemas/AggregateModeEnum"},{"type":"null"}],"description":"How to aggregate across environments. Unset defaults to avg at execution — every panel forecast stores an aggregate"},"originTimestamp":{"type":["number","null"],"description":"Forecast as-of timestamp (ms epoch). Overrides forecastFrom per environment."}},"required":["type","forecastH","targetVars"]},"AggregateModeEnum":{"type":"string","enum":["sum","avg","min","max"]},"PanelInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_intervention"},"interventions":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"},{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"}}]},"description":"A list of interventions or sequences"},"metrics":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the metric"},"sqlQuery":{"type":"string","description":"The SQL query to calculate the metric"},"unit":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}],"description":"Canonical unit id (legacy keys coerced on read)"},"higherIsBetter":{"type":"boolean","default":true,"description":"Whether a higher value is better for this metric"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Temporal evaluation spec for time-aware metrics. Null for static panel models."},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["name","sqlQuery"]},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for intervention. None = all environments"}},"required":["type","interventions","metrics"]},"PanelExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"]},"effectVariable":{"type":["string","null"]},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}]},"forecastHorizonOverride":{"type":["number","null"]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for explanation. None = all environments"}},"required":["type"]},"PanelCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_counterfactual"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/TemporalCounterfactualTargetSchema"}},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}]},"maxChanges":{"type":"number","default":3},"forecastHorizon":{"type":["number","null"]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for counterfactual. None = all environments"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"Multi-environment static panels only: baseline states to improve, applied in every environment in scope. Temporal panels solve from the twin's own trajectory and ignore this."}},"required":["type","targets"]},"PanelOptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/TemporalOptimisationObjectiveSchema"}},"decisionVars":{"type":"array","items":{"type":"string"}},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}]},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}]},"interventionTiming":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TemporalInterventionTimingSchema"}},{"type":"null"}]},"forecastHorizon":{"type":["number","null"]},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for optimisation. None = all environments"}},"required":["type","objectives","decisionVars"]},"PanelParentImpactRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_parent_impact"},"nodes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Nodes to analyze. None = all non-latent nodes with parents"},"nSamples":{"type":"number","default":500,"description":"Samples per do() contrast (static twins only)"},"horizonOverride":{"type":["number","null"],"description":"Attribution forecast window override (temporal twins only)"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for parent impact. None = all environments"}},"required":["type"]},"RootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5}},"required":["type","targetVariable"]},"TemporalRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"anomalyTimestep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5}},"required":["type","targetVariable"]},"PanelRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"anomalyTimestep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type","targetVariable"]},"PanelScenarioSamplesRefSchema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"}},"StaticPanelRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"static_panel_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type","targetVariable"]},"AnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true}},"required":["type"]},"TemporalAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRcaTopK":{"type":"integer","minimum":0,"default":1}},"required":["type"]},"PanelAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRcaTopK":{"type":"integer","minimum":0,"default":1},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"StaticPanelAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"static_panel_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"CausalHealthMonitorRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"causal_health_monitor"},"dataSource":{"$ref":"#/components/schemas/ChmDataSourceSchema","default":"observed"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"forecastHorizon":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true}},"required":["type"]},"ChmDataSourceSchema":{"type":"string","enum":["observed","forecast"]},"PanelCausalHealthMonitorRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_causal_health_monitor"},"dataSource":{"$ref":"#/components/schemas/ChmDataSourceSchema","default":"observed"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"forecastHorizon":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"EnvironmentGroupSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"definition":{"$ref":"#/components/schemas/EnvironmentGroupDefinitionSchema"},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"updatedAt":{"type":["string","null"]},"splitColumn":{"type":["string","null"]},"splitValue":{"type":["string","null"]}},"required":["id","name","definition","createdAt"]},"EnvironmentGroupDefinitionSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["columnValues","environments","statFilters"]},"columnValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},{"type":"null"}]},"statFilters":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"},{"type":"null"}]},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}]}},"required":["mode"]},"EnvStatFilterGroupSchema":{"type":"object","properties":{"booleanOperator":{"type":"string","enum":["AND","OR"]},"filters":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterSchema"},{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"}]}}},"required":["booleanOperator","filters"]},"EnvStatFilterSchema":{"type":"object","properties":{"column":{"type":"string"},"comparisonOperator":{"type":"string"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":["string","number","boolean"]}}]},"reduce":{"anyOf":[{"$ref":"#/components/schemas/EnvStatReduceEnum"},{"type":"null"}]}},"required":["column","comparisonOperator","value"]},"EnvStatReduceEnum":{"type":"string","enum":["value","mean","min","max","any"]},"AutoUpdateSettingsSchema":{"type":"object","properties":{"enabled":{"type":"boolean","default":false},"mode":{"type":"string","enum":["assimilate_only","assimilate_or_retrain"],"default":"assimilate_only"}}}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}","summary":"Get digital twin","description":"Returns the digital twin by id from platform MongoDB. Must belong to the workspace. Includes canonicalInputSchema, suggestedSimulations.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DigitalTwinEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Delete digital twin

> Deletes the twin. Proxies DELETE to data-service so that data-service state (orchestrator, models, runs) is cleaned up; then the platform record would typically be removed by the caller or a follow-up. Requires digital-twins:delete and full permission.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}":{"delete":{"operationId":"delete-api-v1-workspaces-{wsId}-digital-twins-{id}","summary":"Delete digital twin","description":"Deletes the twin. Proxies DELETE to data-service so that data-service state (orchestrator, models, runs) is cleaned up; then the platform record would typically be removed by the caller or a follow-up. Requires digital-twins:delete and full permission.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"}],"responses":{"204":{"description":"No Content"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Update digital twin

> Updates name and/or tags. Only these fields are writable. Stored in platform MongoDB. A name already held by another twin in the workspace is refused with 409 rather than silently suffixed.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UpdateTwinInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"tags":{"type":"array","items":{"type":"string"}}}},"DigitalTwinEnvelope":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/DigitalTwin"}},"required":["data"]},"DigitalTwin":{"type":"object","properties":{"id":{"type":"string"},"organisationId":{"type":"string"},"workspaceId":{"type":"string"},"name":{"type":"string"},"normalizedName":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/DigitalTwinTypeEnum"},"canonicalInputSchema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaEntryModelSchema"}},{"type":"null"}]},"tags":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"status":{"$ref":"#/components/schemas/StatusTypeEnum","default":"active"},"createdAt":{"type":"string"},"suggestedSimulations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SuggestedSimulationSchema"}},{"type":"null"}]},"suggestionsGeneratedAt":{"type":["string","null"]},"environmentGroups":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/EnvironmentGroupSchema"}},{"type":"null"}]},"autoUpdate":{"anyOf":[{"$ref":"#/components/schemas/AutoUpdateSettingsSchema"},{"type":"null"}]},"maintainedBy":{"type":"array","items":{"type":"object","properties":{"applicationId":{"type":"string"},"version":{"type":"string"},"flowId":{"type":"string"}},"required":["applicationId","version","flowId"]}}},"required":["id","organisationId","workspaceId","name","type"]},"DigitalTwinTypeEnum":{"type":"string","enum":["static","temporal","multi-environment-temporal","multi-environment-static"]},"SchemaEntryModelSchema":{"type":"object","properties":{"field":{"type":"string"},"type":{"$ref":"#/components/schemas/SchemaMainTypeEnum"},"subtype":{"anyOf":[{"$ref":"#/components/schemas/SchemaSubTypeEnum"},{"type":"null"}]},"availableTypes":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaMainTypeEnum"}},{"type":"null"}]},"isIndex":{"type":["boolean","null"]},"categories":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"aliases":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"description":{"type":["string","null"]},"displayWidth":{"type":["number","null"]},"originalFormat":{"type":["string","null"]},"displayFormat":{"type":["string","null"]},"unit":{"type":["string","null"]},"unitModifier":{"type":["number","null"]},"dateOrderAssumed":{"type":["boolean","null"]}},"required":["field","type"]},"SchemaMainTypeEnum":{"type":"string","enum":["None","String","Category","Number","Boolean","DateTime","Array","Unknown"]},"SchemaSubTypeEnum":{"type":"string","enum":["Integer","Float","UnsignedInteger","UnsignedFloat","String","Number","Category","Boolean","DateTime"]},"StatusTypeEnum":{"type":"string","enum":["active","deprecated"]},"SuggestedSimulationSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"scenario":{"$ref":"#/components/schemas/DigitalTwinScenarioSchema"},"createdAt":{"type":"string"}},"required":["id","name","description","scenario","createdAt"]},"DigitalTwinScenarioSchema":{"anyOf":[{"$ref":"#/components/schemas/OptimisationScenarioSchema"},{"$ref":"#/components/schemas/StaticInterventionSpecSchema"},{"$ref":"#/components/schemas/TimeSeriesInterventionSpecSchema"},{"$ref":"#/components/schemas/MultiCounterfactualRequestSchema"},{"$ref":"#/components/schemas/PredictionWithUncertaintyRequestSchema"},{"$ref":"#/components/schemas/ExplanationRequestSchema"},{"$ref":"#/components/schemas/ParentImpactRequestSchema"},{"$ref":"#/components/schemas/ForecastWithUncertaintyRequestSchema"},{"$ref":"#/components/schemas/TemporalExplanationRequestSchema"},{"$ref":"#/components/schemas/TemporalCounterfactualRequestSchema"},{"$ref":"#/components/schemas/TemporalOptimisationScenarioSchema"},{"$ref":"#/components/schemas/PanelForecastRequestSchema"},{"$ref":"#/components/schemas/PanelInterventionSpecSchema"},{"$ref":"#/components/schemas/PanelExplanationRequestSchema"},{"$ref":"#/components/schemas/PanelCounterfactualRequestSchema"},{"$ref":"#/components/schemas/PanelOptimisationScenarioSchema"},{"$ref":"#/components/schemas/PanelParentImpactRequestSchema"},{"$ref":"#/components/schemas/RootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/TemporalRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/PanelRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/StaticPanelRootCauseAnalysisRequestSchema"},{"$ref":"#/components/schemas/AnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/TemporalAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/PanelAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/StaticPanelAnomalyDetectionRequestSchema"},{"$ref":"#/components/schemas/CausalHealthMonitorRequestSchema"},{"$ref":"#/components/schemas/PanelCausalHealthMonitorRequestSchema"}]},"OptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/OptimisationObjectiveSchema"},"description":"The objectives to optimize"},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Dead field, ignored by the optimizer: subpopulation scoping goes through segmentDefinitions + enableSegmentInterventions. Kept so stored scenarios still parse."},"decisionVars":{"type":"array","items":{"type":"string"},"description":"Variables that can be manipulated during optimization"},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}],"description":"Constraints on variable values and changes"},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}],"description":"Constraints on metric values"},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Segment definitions for segment-aware interventions and per-segment results"},"enableSegmentInterventions":{"type":"boolean","default":false,"description":"Whether to explore segment-specific interventions"},"interventionTypes":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}],"description":"Map of variable name to intervention type: 'set_value', 'relative_percentage', 'relative_absolute', 'set_probability'"},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}],"description":"Configuration for intervention count optimization"}},"required":["type","objectives","decisionVars"]},"OptimisationObjectiveSchema":{"type":"object","properties":{"direction":{"type":"string","enum":["maximise","minimise"],"description":"The direction of the optimization"},"variable":{"type":"string","description":"A descriptive name for this objective/metric (e.g., 'Total Revenue', 'Customer Churn Rate'). Used as a label, not necessarily a variable in the causal graph."},"metricSqlQuery":{"type":"string","description":"SQL query to calculate the metric"},"unit":{"$ref":"#/components/schemas/objectiveUnitReadSchema","description":"Canonical unit id (legacy keys coerced on read). Omit for objectives without a meaningful unit."},"weight":{"type":"number","default":1,"description":"Weight of this objective in multi-objective optimization"},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric"},"target":{"anyOf":[{"$ref":"#/components/schemas/OptimisationTargetSchema"},{"type":"null"}],"description":"Optional target specification (absolute value or percentage improvement)"},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["direction","variable","metricSqlQuery"]},"objectiveUnitReadSchema":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}]},"OptimisationTargetSchema":{"type":"object","properties":{"type":{"type":"string","enum":["absolute","percentage"],"default":"percentage","description":"Whether target is an absolute value or percentage change from baseline"},"value":{"type":["number","null"],"description":"Target value. None means just optimize in the specified direction without a specific target."}}},"ConditionSchema":{"type":"object","properties":{"variable":{"type":"string"},"operator":{"type":"string","enum":["eq","ne","gt","lt","ge","le","in","not_in"]},"value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":["number","string","boolean"]}}]}},"required":["variable","operator","value"]},"VariableConstraintSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable this constraint applies to"},"type":{"type":"string","enum":["range","set","conditional"],"description":"Type of constraint"},"minValue":{"type":["number","null"],"description":"Minimum allowed value (for range type)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value (for range type)"},"allowedValues":{"anyOf":[{"type":"array","items":{"type":["string","number","boolean"]}},{"type":"null"}],"description":"List of allowed values (for set type)"},"maxChangePercent":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Maximum percentage change from baseline allowed"},"conditionalAllowedValues":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionalAllowedValuesSchema"}},{"type":"null"}],"description":"Conditional allowed values based on other variable values (for conditional type)"}},"required":["variable","type"]},"ConditionalAllowedValuesSchema":{"type":"object","properties":{"condition":{"type":"object","properties":{"variable":{"type":"string"},"operator":{"type":"string","enum":["eq","ne","gt","lt","ge","le","in","not_in"]},"value":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"boolean"},{"type":"array","items":{"type":["number","string","boolean"]}}]}},"required":["variable","operator","value"],"description":"The condition that must be met for this constraint to apply"},"allowedValues":{"anyOf":[{"type":"array","items":{"type":["string","number","boolean"]}},{"type":"null"}],"description":"Values allowed when condition is met (used for categorical/boolean variables)"},"minValue":{"type":["number","null"],"description":"Minimum allowed value when condition is met (used for numeric variables)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value when condition is met (used for numeric variables)"}},"required":["condition"]},"MetricConstraintSchema":{"type":"object","properties":{"metricName":{"type":"string","description":"Name of the metric being constrained"},"sqlQuery":{"type":"string","description":"SQL query to calculate the metric"},"constraintType":{"type":"string","enum":["min_value","max_value","max_decrease_percent","max_increase_percent","fixed_boolean"],"description":"Type of constraint"},"value":{"type":["number","null"],"description":"Constraint value (absolute for min/max, percentage for percent types)"},"booleanValue":{"type":["boolean","null"],"description":"Boolean value for fixed_boolean constraint type"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Window the constraint is evaluated over on a temporal twin. Null means the whole forecast horizon from the first forecast step."}},"required":["metricName","sqlQuery","constraintType"]},"TemporalMetricSpecSchema":{"type":"object","properties":{"startDate":{"type":["string","null"],"description":"Evaluation start as an ISO date (UTC); the backend resolves it into startTimestampMs"},"endDate":{"type":["string","null"],"description":"Evaluation end as an ISO date (UTC), inclusive"},"startTimestampMs":{"type":["number","null"],"description":"Start timestamp (ms). Without an end the window runs intervalSteps grid steps from here; a start alone is one grid step."},"endTimestampMs":{"type":["number","null"],"description":"End timestamp (ms) inclusive. Windows narrower than one model step widen to one full step."},"intervalSteps":{"type":["number","null"],"description":"Window length in model steps when no end is given, counted from the start (or the first forecast step). Ignored when an end is set."}}},"SegmentDefinitionSchema":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the segment (e.g., 'high_spenders')"},"description":{"type":["string","null"],"description":"User-friendly description of the segment"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"},"description":"List of conditions (ANDed together) defining the segment membership."}},"required":["id","conditions"]},"InterventionCountConfigSchema":{"type":"object","properties":{"maxInterventions":{"anyOf":[{"type":"number","minimum":1},{"type":"null"}],"description":"Maximum number of changes per plan. None means no limit."},"optimizeCount":{"type":"boolean","default":true,"description":"Whether to treat intervention count as an implicit minimization objective"}}},"StaticInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"intervention"},"interventions":{"type":"array","items":{"$ref":"#/components/schemas/InterventionSchema"},"description":"A list of interventions with their respective conditions"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/MetricSchema"},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions for targeted analysis of results."}},"required":["type","interventions","metrics"]},"InterventionSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable to intervene on"},"valueSpec":{"anyOf":[{"$ref":"#/components/schemas/SetValueSpecSchema"},{"$ref":"#/components/schemas/RelativeChangeSpecSchema"},{"$ref":"#/components/schemas/SetProbabilitySpecSchema"},{"$ref":"#/components/schemas/AdjustProbabilitySpecSchema"},{"$ref":"#/components/schemas/SetMembersSpecSchema"},{"$ref":"#/components/schemas/RangeValueSpecSchema"}],"description":"Specification of how to modify the variable."},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Optional conditions defining the subpopulation for intervention."},"detachFormula":{"type":["boolean","null"],"description":"Allow this intervention on a computed value. Its formula is switched off for the run: the variable takes the intervened value instead of being recomputed from its inputs, and its inputs do not move to match."}},"required":["variable","valueSpec"]},"SetValueSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_value"},"value":{"type":["number","string","boolean"],"description":"The specific value to set the variable to (in its original domain)."}},"required":["type","value"]},"RelativeChangeSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"relative_change"},"mode":{"type":"string","enum":["percentage","absolute"],"description":"Whether the change is a percentage or an absolute amount."},"value":{"type":"number","description":"The amount of change (e.g., 10 for +10%, -5 for -5 units)."}},"required":["type","mode","value"]},"SetProbabilitySpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_probability"},"category":{"type":["string","number","boolean"],"description":"The target category value (in its original domain) whose probability will be set."},"probability":{"type":"number","minimum":0,"maximum":1,"description":"The desired probability for the specified category (0.0 to 1.0). Other probabilities will be renormalized."}},"required":["type","category","probability"]},"AdjustProbabilitySpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"adjust_probability"},"category":{"type":["string","number","boolean"],"description":"The target category value whose probability will be adjusted."},"delta":{"type":"number","description":"Percentage-point shift (e.g. 10 means +10pp, -5 means -5pp)."}},"required":["type","category","delta"]},"SetMembersSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"set_members"},"include":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Members to include in the set"},"exclude":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Members to exclude from the set"},"size":{"type":["number","null"],"description":"Fix the set size"},"replace":{"type":"boolean","description":"If true, zero out all members not in include"}},"required":["type"]},"RangeValueSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"range"},"from":{"type":["number","null"],"description":"First value of the grid, in the variable's original domain. Omit to start at the low end of the observed range."},"to":{"type":["number","null"],"description":"Last value of the grid, in the variable's original domain. Omit to end at the high end of the observed range."},"steps":{"anyOf":[{"type":"integer","minimum":2,"maximum":50},{"type":"null"}],"description":"Number of evenly spaced grid points, inclusive of both bounds (2-50). Omit to let the twin family pick — 20 for a static sweep, fewer for temporal families where one point is a whole forecast."}},"required":["type"]},"MetricSchema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the metric"},"sqlQuery":{"type":"string","description":"The SQL query to calculate the metric"},"unit":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}],"description":"Canonical unit id (legacy keys coerced on read)"},"higherIsBetter":{"type":"boolean","default":true,"description":"Whether a higher value is better for this metric"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Temporal evaluation window for time-aware metrics. Null means the whole forecast horizon from the first forecast step. Ignored by non-temporal twins."},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["name","sqlQuery"]},"TimeSeriesInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_intervention"},"interventions":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"},{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"}}]},"description":"A list of time series interventions or sequences (nested lists) for time series models"},"metrics":{"type":"array","items":{"$ref":"#/components/schemas/MetricSchema"},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions for targeted analysis of results."}},"required":["type","interventions","metrics"]},"TimeSeriesInterventionSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The variable to intervene on"},"valueSpec":{"anyOf":[{"$ref":"#/components/schemas/SetValueSpecSchema"},{"$ref":"#/components/schemas/RelativeChangeSpecSchema"},{"$ref":"#/components/schemas/SetProbabilitySpecSchema"},{"$ref":"#/components/schemas/AdjustProbabilitySpecSchema"},{"$ref":"#/components/schemas/SetMembersSpecSchema"},{"$ref":"#/components/schemas/RangeValueSpecSchema"}],"description":"Specification of how to modify the variable."},"conditions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ConditionSchema"}},{"type":"null"}],"description":"Optional conditions defining the subpopulation for intervention."},"detachFormula":{"type":["boolean","null"],"description":"Allow this intervention on a computed value. Its formula is switched off for the run: the variable takes the intervened value instead of being recomputed from its inputs, and its inputs do not move to match."},"timestamp":{"type":["number","null"],"description":"The timestamp to intervene at (for temporal models)"},"persistent":{"type":["boolean","null"],"description":"If True, intervention persists from timestamp onwards. If False, applies only at that timestamp. Only used for temporal models."},"durationSteps":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Hold the value for this many steps starting at the timestamp, then release. Overrides persistent when set (>1). Only used for temporal models."},"rampSteps":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Number of steps to gradually reach this intervention's value. Within a sequence, ramps from the previous state; on a single intervention, ramps from baseline (relative changes only)."}},"required":["variable","valueSpec"]},"MultiCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"counterfactual"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"List of initial samples"},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}],"description":"Datalake reference replacing inline samples"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/CounterfactualTargetSchema"},"description":"Target variables to change for all samples"},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}],"description":"Constraints defining the search space (applied individually per sample). Variables not mentioned or without a FixedConstraint are implicitly changeable."},"maxChanges":{"type":"number","default":3,"description":"Maximum number of variables to change per sample"}},"required":["type","targets"]},"ScenarioSamplesRefSchema":{"type":"object","properties":{"key":{"type":"string","description":"Datalake object key holding the JSON-encoded samples array"},"format":{"type":"string","enum":["json"],"default":"json"},"rowCount":{"type":"integer","minimum":0,"description":"Number of rows in the referenced blob"}},"required":["key","rowCount"]},"CounterfactualTargetSchema":{"type":"object","properties":{"variable":{"type":"string","description":"The target variable name"},"value":{"description":"The desired value for this target variable"},"matchMode":{"$ref":"#/components/schemas/CounterfactualMatchModeSchema","default":"tolerance","description":"How to decide whether a prediction meets this target: tolerance band, >= target, or <= target."},"toleranceType":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualToleranceTypeSchema"},{"type":"null"}],"description":"When matchMode='tolerance': percentage of |target| or absolute units."},"toleranceValue":{"type":["number","null"],"description":"When matchMode='tolerance': width of the tolerance band (>=0). None/0 means exact match."}},"required":["variable"]},"CounterfactualMatchModeSchema":{"type":"string","enum":["tolerance","orMore","orLess"]},"CounterfactualToleranceTypeSchema":{"type":"string","enum":["percentage","absolute"]},"CounterfactualVariableConstraintSchema":{"anyOf":[{"$ref":"#/components/schemas/RangeConstraintSchema"},{"$ref":"#/components/schemas/SetConstraintSchema"},{"$ref":"#/components/schemas/FixedConstraintSchema"}]},"RangeConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"range"},"minValue":{"type":["number","null"],"description":"Minimum allowed value (inclusive)"},"maxValue":{"type":["number","null"],"description":"Maximum allowed value (inclusive)"}},"required":["type"]},"SetConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"set"},"allowedValues":{"type":"array","items":{"type":["string","number","boolean"]},"description":"List of explicitly allowed values."}},"required":["type","allowedValues"]},"FixedConstraintSchema":{"type":"object","properties":{"type":{"type":"string","const":"fixed"}},"required":["type"]},"PredictionWithUncertaintyRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"prediction"},"sample":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"Samples to predict for"},"sampleRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}],"description":"Datalake reference replacing inline sample"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to predict"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"}},"required":["type","targetVars"]},"ExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"],"description":"The cause variable to explain"},"effectVariable":{"type":["string","null"],"description":"The effect variable to explain"},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"The segments to explain"}},"required":["type"]},"ExplanationModeSchema":{"type":"string","enum":["directional","discovery","impact"]},"ParentImpactRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"parent_impact"},"nodes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Nodes to analyze. None = all non-latent nodes with parents"},"nSamples":{"type":"number","default":500,"description":"Samples per do() contrast (static twins only)"},"horizonOverride":{"type":["number","null"],"description":"Attribution forecast window override (temporal twins only)"}},"required":["type"]},"ForecastWithUncertaintyRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"forecast"},"forecastFrom":{"type":["number","null"],"description":"Timestamp of the forecast start"},"forecastH":{"type":"number","description":"Number of steps to forecast"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to forecast"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"},"originTimestamp":{"type":["number","null"],"description":"Forecast as-of timestamp (ms epoch). Overrides forecastFrom when set."}},"required":["type","forecastH","targetVars"]},"TemporalExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"]},"effectVariable":{"type":["string","null"]},"causeVariables":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Multi-select cause variables for directional mode"},"effectVariables":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Multi-select effect variables for directional mode"},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}]},"forecastHorizonOverride":{"type":["number","null"]}},"required":["type"]},"TemporalCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_counterfactual"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/TemporalCounterfactualTargetSchema"}},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}]},"maxChanges":{"type":"number","default":3},"forecastHorizon":{"type":["number","null"]}},"required":["type","targets"]},"TemporalCounterfactualTargetSchema":{"type":"object","properties":{"variable":{"type":"string"},"value":{},"timestamp":{"type":["number","null"]},"aggregation":{"type":"string","enum":["point","mean","cumulative"],"default":"point"},"targetMode":{"$ref":"#/components/schemas/TargetModeSchema"},"matchMode":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualMatchModeSchema"},{"type":"null"}],"description":"Left unset, each aggregation keeps its own rule: a 10% band for point and mean, at-least for cumulative. A value overrides that."},"toleranceType":{"anyOf":[{"$ref":"#/components/schemas/CounterfactualToleranceTypeSchema"},{"type":"null"}]},"toleranceValue":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}]}},"required":["variable"]},"TargetModeSchema":{"type":"string","enum":["absolute","relative_percentage","relative_absolute"],"default":"absolute"},"TemporalOptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/TemporalOptimisationObjectiveSchema"}},"decisionVars":{"type":"array","items":{"type":"string"}},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}]},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}]},"interventionTiming":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TemporalInterventionTimingSchema"}},{"type":"null"}]},"forecastHorizon":{"type":"number"},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}]}},"required":["type","objectives","decisionVars","forecastHorizon"]},"TemporalOptimisationObjectiveSchema":{"type":"object","properties":{"direction":{"type":"string","enum":["maximise","minimise"]},"variable":{"type":"string"},"metricSqlQuery":{"type":"string"},"weight":{"type":"number","default":1},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}]},"discountFactor":{"type":"number","default":1},"conceptId":{"type":["string","null"]},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}]}},"required":["direction","variable","metricSqlQuery"]},"TemporalInterventionTimingSchema":{"type":"object","properties":{"variable":{"type":"string"},"earliestTimestamp":{"type":["number","null"]},"latestTimestamp":{"type":["number","null"]},"allowRamping":{"type":"boolean","default":true},"maxRampSteps":{"type":["number","null"]}},"required":["variable"]},"PanelForecastRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_forecast"},"forecastH":{"type":"number","description":"Number of steps to forecast"},"targetVars":{"type":"array","items":{"type":"string"},"description":"Target variables to forecast"},"confidenceLevel":{"type":["number","null"],"default":0.95,"description":"Confidence level for intervals"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments to forecast. None = all environments"},"aggregateMode":{"anyOf":[{"$ref":"#/components/schemas/AggregateModeEnum"},{"type":"null"}],"description":"How to aggregate across environments. Unset defaults to avg at execution — every panel forecast stores an aggregate"},"originTimestamp":{"type":["number","null"],"description":"Forecast as-of timestamp (ms epoch). Overrides forecastFrom per environment."}},"required":["type","forecastH","targetVars"]},"AggregateModeEnum":{"type":"string","enum":["sum","avg","min","max"]},"PanelInterventionSpecSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_intervention"},"interventions":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"},{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesInterventionSchema"}}]},"description":"A list of interventions or sequences"},"metrics":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the metric"},"sqlQuery":{"type":"string","description":"The SQL query to calculate the metric"},"unit":{"allOf":[{"anyOf":[{"not":{}},{"type":["string","null"]}]},{"type":["string","null"]}],"description":"Canonical unit id (legacy keys coerced on read)"},"higherIsBetter":{"type":"boolean","default":true,"description":"Whether a higher value is better for this metric"},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalMetricSpecSchema"},{"type":"null"}],"description":"Temporal evaluation spec for time-aware metrics. Null for static panel models."},"conceptId":{"type":["string","null"],"description":"Ontology metric concept this SQL was materialised from, when picked from the ontology"},"conceptEditVersion":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"editVersion of the source concept at materialisation time; drift is detected against the live concept"}},"required":["name","sqlQuery"]},"description":"SQL queries to calculate the metrics of interest."},"variablesRelevantToMetric":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Variables causally relevant to the metric."},"segmentDefinitions":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}],"description":"Optional list of segment definitions"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for intervention. None = all environments"}},"required":["type","interventions","metrics"]},"PanelExplanationRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_explanation"},"explanationMode":{"anyOf":[{"$ref":"#/components/schemas/ExplanationModeSchema"},{"type":"null"}],"description":"Explicit explanation mode selection"},"causeVariable":{"type":["string","null"]},"effectVariable":{"type":["string","null"]},"segments":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SegmentDefinitionSchema"}},{"type":"null"}]},"forecastHorizonOverride":{"type":["number","null"]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for explanation. None = all environments"}},"required":["type"]},"PanelCounterfactualRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_counterfactual"},"targets":{"type":"array","items":{"$ref":"#/components/schemas/TemporalCounterfactualTargetSchema"}},"constraints":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CounterfactualVariableConstraintSchema"}},{"type":"null"}]},"maxChanges":{"type":"number","default":3},"forecastHorizon":{"type":["number","null"]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for counterfactual. None = all environments"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"Multi-environment static panels only: baseline states to improve, applied in every environment in scope. Temporal panels solve from the twin's own trajectory and ignore this."}},"required":["type","targets"]},"PanelOptimisationScenarioSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_optimisation"},"objectives":{"type":"array","items":{"$ref":"#/components/schemas/TemporalOptimisationObjectiveSchema"}},"decisionVars":{"type":"array","items":{"type":"string"}},"variableConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/VariableConstraintSchema"}},{"type":"null"}]},"metricConstraints":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/MetricConstraintSchema"}},{"type":"null"}]},"interventionTiming":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TemporalInterventionTimingSchema"}},{"type":"null"}]},"forecastHorizon":{"type":["number","null"]},"interventionCountConfig":{"anyOf":[{"$ref":"#/components/schemas/InterventionCountConfigSchema"},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for optimisation. None = all environments"}},"required":["type","objectives","decisionVars"]},"PanelParentImpactRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_parent_impact"},"nodes":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Nodes to analyze. None = all non-latent nodes with parents"},"nSamples":{"type":"number","default":500,"description":"Samples per do() contrast (static twins only)"},"horizonOverride":{"type":["number","null"],"description":"Attribution forecast window override (temporal twins only)"},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Specific environments for parent impact. None = all environments"}},"required":["type"]},"RootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5}},"required":["type","targetVariable"]},"TemporalRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"anomalyTimestep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5}},"required":["type","targetVariable"]},"PanelRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"anomalyTimestep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type","targetVariable"]},"PanelScenarioSamplesRefSchema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"}},"StaticPanelRootCauseAnalysisRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"static_panel_root_cause_analysis"},"targetVariable":{"type":"string"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type","targetVariable"]},"AnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true}},"required":["type"]},"TemporalAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"temporal_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRcaTopK":{"type":"integer","minimum":0,"default":1}},"required":["type"]},"PanelAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRcaTopK":{"type":"integer","minimum":0,"default":1},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"StaticPanelAnomalyDetectionRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"static_panel_anomaly_detection"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"CausalHealthMonitorRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"causal_health_monitor"},"dataSource":{"$ref":"#/components/schemas/ChmDataSourceSchema","default":"observed"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"forecastHorizon":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true}},"required":["type"]},"ChmDataSourceSchema":{"type":"string","enum":["observed","forecast"]},"PanelCausalHealthMonitorRequestSchema":{"type":"object","properties":{"type":{"type":"string","const":"panel_causal_health_monitor"},"dataSource":{"$ref":"#/components/schemas/ChmDataSourceSchema","default":"observed"},"samples":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"samplesRef":{"anyOf":[{"$ref":"#/components/schemas/ScenarioSamplesRefSchema"},{"type":"null"}]},"forecastHorizon":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"startStep":{"type":["number","null"]},"endStep":{"type":["number","null"]},"targetFpr":{"type":"number","minimum":0.0001,"maximum":0.1,"default":0.005},"parentToleranceSigma":{"type":"number","default":0.5},"autoRca":{"type":"boolean","default":true},"environments":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"panelSamples":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":{}}}},{"type":"null"}]},"panelSamplesRef":{"anyOf":[{"$ref":"#/components/schemas/PanelScenarioSamplesRefSchema"},{"type":"null"}]}},"required":["type"]},"EnvironmentGroupSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"definition":{"$ref":"#/components/schemas/EnvironmentGroupDefinitionSchema"},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"updatedAt":{"type":["string","null"]},"splitColumn":{"type":["string","null"]},"splitValue":{"type":["string","null"]}},"required":["id","name","definition","createdAt"]},"EnvironmentGroupDefinitionSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["columnValues","environments","statFilters"]},"columnValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},{"type":"null"}]},"statFilters":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"},{"type":"null"}]},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}]}},"required":["mode"]},"EnvStatFilterGroupSchema":{"type":"object","properties":{"booleanOperator":{"type":"string","enum":["AND","OR"]},"filters":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterSchema"},{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"}]}}},"required":["booleanOperator","filters"]},"EnvStatFilterSchema":{"type":"object","properties":{"column":{"type":"string"},"comparisonOperator":{"type":"string"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":["string","number","boolean"]}}]},"reduce":{"anyOf":[{"$ref":"#/components/schemas/EnvStatReduceEnum"},{"type":"null"}]}},"required":["column","comparisonOperator","value"]},"EnvStatReduceEnum":{"type":"string","enum":["value","mean","min","max","any"]},"AutoUpdateSettingsSchema":{"type":"object","properties":{"enabled":{"type":"boolean","default":false},"mode":{"type":"string","enum":["assimilate_only","assimilate_or_retrain"],"default":"assimilate_only"}}}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}":{"patch":{"operationId":"patch-api-v1-workspaces-{wsId}-digital-twins-{id}","summary":"Update digital twin","description":"Updates name and/or tags. Only these fields are writable. Stored in platform MongoDB. A name already held by another twin in the workspace is refused with 409 rather than silently suffixed.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTwinInput"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DigitalTwinEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Import digital twin from export zip

> Imports a digital twin from an export zip. Request body: raw zip bytes (Content-Type application/zip, filename via x-filename header, must contain twin.json). Max 512 MB on this route; larger imports go through the platform UI. Optional query param webhookUrl — POSTed once (best effort, unsigned) at the terminal state. Returns 202 with jobId; poll links.self. Requires digital-twins:write scope.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"BinaryUpload":{"description":"Raw file bytes"},"AsyncJobAccepted":{"type":"object","properties":{"data":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","description":"pending until the job reaches a terminal status"},"createdAt":{"type":"string"},"links":{"type":"object","properties":{"self":{"type":"string","description":"Poll this until the status is terminal"},"cancel":{"type":"string"}},"required":["self"]}},"required":["jobId","status","links"],"description":"Envelope for asynchronous pipeline work. Poll links.self until the job reaches a terminal status."}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/import":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-import","summary":"Import digital twin from export zip","description":"Imports a digital twin from an export zip. Request body: raw zip bytes (Content-Type application/zip, filename via x-filename header, must contain twin.json). Max 512 MB on this route; larger imports go through the platform UI. Optional query param webhookUrl — POSTed once (best effort, unsigned) at the terminal state. Returns 202 with jobId; poll links.self. Requires digital-twins:write scope.","tags":["Digital Twins"],"parameters":[{"in":"query","name":"webhookUrl","required":false,"schema":{"type":"string","description":"Called with the job result when the import reaches a terminal state."},"description":"Called with the job result when the import reaches a terminal state."},{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"in":"header","name":"x-filename","required":true,"schema":{"type":"string","description":"Filename to store the upload under"},"description":"Filename to store the upload under"}],"requestBody":{"content":{"application/zip":{"schema":{"$ref":"#/components/schemas/BinaryUpload"}}}},"responses":{"202":{"description":"Accepted; poll the linked resource for completion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncJobAccepted"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## List environment groups

> Multi-environment (panel) twins: returns the twin's saved environment groups. A group is a named, declarative rule over the twin's environment columns — mode \`columnValues\` (allowed values per environment column), \`environments\` (exact combos, each {column: value}), or \`statFilters\` (select environments by per-environment aggregates over any twin column). Groups belong to the twin, not to a version, so they survive retraining; their concrete membership only exists relative to a version and is computed by POST .../versions/{vId}/environment-groups/resolve. Single-environment twins have none.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"EnvironmentGroupListEnvelope":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EnvironmentGroupSchema"}}},"required":["data"]},"EnvironmentGroupSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"definition":{"$ref":"#/components/schemas/EnvironmentGroupDefinitionSchema"},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"updatedAt":{"type":["string","null"]},"splitColumn":{"type":["string","null"]},"splitValue":{"type":["string","null"]}},"required":["id","name","definition","createdAt"]},"EnvironmentGroupDefinitionSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["columnValues","environments","statFilters"]},"columnValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},{"type":"null"}]},"statFilters":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"},{"type":"null"}]},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}]}},"required":["mode"]},"EnvStatFilterGroupSchema":{"type":"object","properties":{"booleanOperator":{"type":"string","enum":["AND","OR"]},"filters":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterSchema"},{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"}]}}},"required":["booleanOperator","filters"]},"EnvStatFilterSchema":{"type":"object","properties":{"column":{"type":"string"},"comparisonOperator":{"type":"string"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":["string","number","boolean"]}}]},"reduce":{"anyOf":[{"$ref":"#/components/schemas/EnvStatReduceEnum"},{"type":"null"}]}},"required":["column","comparisonOperator","value"]},"EnvStatReduceEnum":{"type":"string","enum":["value","mean","min","max","any"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/environment-groups":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-environment-groups","summary":"List environment groups","description":"Multi-environment (panel) twins: returns the twin's saved environment groups. A group is a named, declarative rule over the twin's environment columns — mode `columnValues` (allowed values per environment column), `environments` (exact combos, each {column: value}), or `statFilters` (select environments by per-environment aggregates over any twin column). Groups belong to the twin, not to a version, so they survive retraining; their concrete membership only exists relative to a version and is computed by POST .../versions/{vId}/environment-groups/resolve. Single-environment twins have none.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentGroupListEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Create an environment group

> Multi-environment (panel) twins: saves a named environment group on the twin. The id is minted server-side. Names are unique per twin and a twin is capped at 200 groups — both are 409 Conflict, not validation errors. The definition is stored verbatim and is not resolved here: a rule naming a column no version has is accepted and reports itself as unresolvable when resolved against a version. Resolve it with POST .../versions/{vId}/environment-groups/resolve, aggregate a scoped graph with POST .../versions/{vId}/graph/slice, or scope a run with \`environmentGroupIds\` on POST /simulations.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"CreateEnvironmentGroupInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"Display name; unique per twin"},"definition":{"type":"object","properties":{"mode":{"type":"string","enum":["columnValues","environments","statFilters"]},"columnValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},{"type":"null"}]},"statFilters":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"},{"type":"null"}]},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}]}},"required":["mode"],"description":"The declarative membership rule: mode columnValues (allowed values per environment column), environments (exact combos), or statFilters (per-environment aggregates over any twin column)"}},"required":["name","definition"]},"EnvStatFilterGroupSchema":{"type":"object","properties":{"booleanOperator":{"type":"string","enum":["AND","OR"]},"filters":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterSchema"},{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"}]}}},"required":["booleanOperator","filters"]},"EnvStatFilterSchema":{"type":"object","properties":{"column":{"type":"string"},"comparisonOperator":{"type":"string"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":["string","number","boolean"]}}]},"reduce":{"anyOf":[{"$ref":"#/components/schemas/EnvStatReduceEnum"},{"type":"null"}]}},"required":["column","comparisonOperator","value"]},"EnvStatReduceEnum":{"type":"string","enum":["value","mean","min","max","any"]},"EnvironmentGroupEnvelope":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EnvironmentGroupSchema"}},"required":["data"]},"EnvironmentGroupSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"definition":{"$ref":"#/components/schemas/EnvironmentGroupDefinitionSchema"},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"updatedAt":{"type":["string","null"]},"splitColumn":{"type":["string","null"]},"splitValue":{"type":["string","null"]}},"required":["id","name","definition","createdAt"]},"EnvironmentGroupDefinitionSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["columnValues","environments","statFilters"]},"columnValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},{"type":"null"}]},"statFilters":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"},{"type":"null"}]},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}]}},"required":["mode"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/environment-groups":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-environment-groups","summary":"Create an environment group","description":"Multi-environment (panel) twins: saves a named environment group on the twin. The id is minted server-side. Names are unique per twin and a twin is capped at 200 groups — both are 409 Conflict, not validation errors. The definition is stored verbatim and is not resolved here: a rule naming a column no version has is accepted and reports itself as unresolvable when resolved against a version. Resolve it with POST .../versions/{vId}/environment-groups/resolve, aggregate a scoped graph with POST .../versions/{vId}/graph/slice, or scope a run with `environmentGroupIds` on POST /simulations.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEnvironmentGroupInput"}}}},"responses":{"201":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentGroupEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Start digital twin export

> Starts an async export of the digital twin as a portable zip: twin metadata, selected versions with their trained model params (full serialized parameters including tree ensembles), and optionally simulation runs. Body (all optional): includeRuns, versions (ids), environments (panel twins), webhookUrl (POSTed once, best effort, at the terminal state). Returns 202 with jobId; poll links.self and fetch links.download when completed. The zip round-trips through POST digital-twins/import.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"ExportTwinInput":{"type":"object","properties":{"includeRuns":{"type":"boolean","description":"Include simulation run artifacts in the export (default false)"},"versions":{"type":"array","items":{"type":"string"},"description":"Version ids to export; all versions when omitted"},"environments":{"type":"array","items":{"type":"string"},"description":"Panel twins: environment keys to export; all environments when omitted"},"webhookUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Optional URL called once when the export completes"}}},"AsyncJobAccepted":{"type":"object","properties":{"data":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","description":"pending until the job reaches a terminal status"},"createdAt":{"type":"string"},"links":{"type":"object","properties":{"self":{"type":"string","description":"Poll this until the status is terminal"},"cancel":{"type":"string"}},"required":["self"]}},"required":["jobId","status","links"],"description":"Envelope for asynchronous pipeline work. Poll links.self until the job reaches a terminal status."}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/export":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-export","summary":"Start digital twin export","description":"Starts an async export of the digital twin as a portable zip: twin metadata, selected versions with their trained model params (full serialized parameters including tree ensembles), and optionally simulation runs. Body (all optional): includeRuns, versions (ids), environments (panel twins), webhookUrl (POSTed once, best effort, at the terminal state). Returns 202 with jobId; poll links.self and fetch links.download when completed. The zip round-trips through POST digital-twins/import.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportTwinInput"}}}},"responses":{"202":{"description":"Accepted; poll the linked resource for completion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncJobAccepted"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## List versions

> Lists all versions of this digital twin. Paginated (limit, cursor). Read from platform MongoDB (digitalTwinVersion collection). Versions carry lifecycleState, causalGraph, and the data they model as datasetId (a derived dataset) or sourceId (a raw source) — whichever the twin was created with.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"DigitalTwinVersionListEnvelope":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DigitalTwinVersion"}},"pagination":{"type":"object","properties":{"cursor":{"type":"string","description":"Pass back as ?cursor= to fetch the next page"},"hasMore":{"type":"boolean","description":"Whether a further page exists"},"total":{"type":"number","description":"Total matching rows, when the query can count them"}},"required":["hasMore"]}},"required":["data","pagination"]},"DigitalTwinVersion":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"twinId":{"type":"string"},"organisationId":{"type":"string"},"workspaceId":{"type":"string"},"versionMajor":{"type":"number","minimum":0},"versionMinor":{"type":"number","minimum":0},"versionPatch":{"type":"number","minimum":0},"version":{"type":["string","null"]},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"derivedFromVersionId":{"type":["string","null"]},"changelog":{"anyOf":[{"$ref":"#/components/schemas/ChangeLogSchema"},{"type":"null"}]},"datasetId":{"type":"string"},"type":{"$ref":"#/components/schemas/DigitalTwinTypeEnum"},"inputFields":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaEntryModelSchema"}},{"type":"null"}]},"temporalDependencies":{"anyOf":[{"$ref":"#/components/schemas/TemporalDependenciesSchema"},{"type":"null"}]},"timeSeriesMetadata":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesMetadataSchema"},{"type":"null"}]},"granularity":{"type":["string","null"]},"fixedSubGraph":{"anyOf":[{"$ref":"#/components/schemas/FixedSubGraphSchema"},{"type":"null"}]},"variableRoles":{"anyOf":[{"$ref":"#/components/schemas/VariableRolesSchema"},{"type":"null"}]},"derivedColumns":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/DtDerivedColumnInfoSchema"}},{"type":"null"}]},"dataSignature":{"type":"string"},"configSignature":{"type":"string"},"nTrainSamples":{"type":["number","null"]},"causalGraph":{"type":"array","items":{"$ref":"#/components/schemas/CausalRelationshipSchema"}},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/CausalNodeSchema"}},"evaluation":{"anyOf":[{"$ref":"#/components/schemas/EvaluationResultSchema"},{"type":"null"}]},"panelEvaluation":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/EvaluationResultSchema"}},{"type":"null"}]},"graphRecommendations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/GraphRecommendationsSchema"}},{"type":"null"}]},"environmentColumns":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"selectedEnvironmentColumns":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"selectedTimeColumnName":{"type":["string","null"]},"environmentSelection":{"anyOf":[{"$ref":"#/components/schemas/EnvironmentSelectionSchema"},{"type":"null"}]},"extraOps":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/OperationSchema"}},{"type":"null"}]},"nEnvironments":{"type":["number","null"]},"latentClusters":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/LatentClusterInfoSchema"}},{"type":"null"}]},"latentDiscoveryConfig":{"anyOf":[{"$ref":"#/components/schemas/LatentDiscoveryConfigSchema"},{"type":"null"}]},"nodeDomains":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"]}},{"type":"null"}]},"lastTimestampMs":{"type":["number","null"]},"headCommit":{"anyOf":[{"type":"integer"},{"type":"null"}]},"trainedWindowSignature":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]},"trainedWindowProfile":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ColumnWindowProfileSchema"}},{"type":"null"}]},"resolvedInputs":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"datasetId":{"type":"string"},"versionId":{"type":["string","null"]},"deltaVersion":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["datasetId"]}},{"type":"null"}]},"updateEligibility":{"anyOf":[{"type":"object","properties":{"updateMode":{"type":"string","enum":["assimilable","retrain_required","up_to_date","unsupported"]},"reasons":{"type":"array","items":{"type":"string"},"default":[]},"newRows":{"type":["number","null"]},"fromTsMs":{"type":["number","null"]},"toTsMs":{"type":["number","null"]},"historyDiff":{"anyOf":[{"$ref":"#/components/schemas/HistoryDiffSchema"},{"type":"null"}]}},"required":["updateMode"]},{"type":"null"}]},"trainingStages":{"anyOf":[{"type":"object","properties":{"confounderModelling":{"type":"boolean"},"equationDiscovery":{"type":"boolean"},"lagScreening":{"type":["boolean","null"]},"evalHorizons":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/EvalHorizonSchema"}},{"type":"null"}]}},"required":["confounderModelling","equationDiscovery"]},{"type":"null"}]},"timeComponent":{"anyOf":[{"$ref":"#/components/schemas/TimeComponentArtifactSchema"},{"type":"null"}]},"causalAlgorithmVersion":{"type":["string","null"]},"digitalTwinAlgorithmVersion":{"type":["string","null"]},"shardCount":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"maxLag":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"layout":{"anyOf":[{"type":"object","properties":{"success":{"type":"boolean"},"positions":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},{"type":"null"}]},"edgeWaypoints":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},{"type":"null"}]}},"required":["success"]},{"type":"null"}]},"lifecycleState":{"$ref":"#/components/schemas/LifecycleStateEnum","default":"created"},"currentTaskId":{"type":["string","null"]},"failureContext":{"anyOf":[{"$ref":"#/components/schemas/FailureContextSchema"},{"type":"null"}]},"traces":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"start":{"type":["string","null"]},"end":{"type":["string","null"]},"name":{"type":["string","null"]}}}},{"type":"null"}]},"arrayFeatureMap":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"arrayFeatureToBase":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]}},"required":["id","twinId","organisationId","workspaceId","versionMajor","versionMinor","versionPatch","datasetId","type","dataSignature","configSignature","causalGraph","nodes"]},{"type":"object","properties":{"id":{"type":"string"},"twinId":{"type":"string"},"organisationId":{"type":"string"},"workspaceId":{"type":"string"},"versionMajor":{"type":"number","minimum":0},"versionMinor":{"type":"number","minimum":0},"versionPatch":{"type":"number","minimum":0},"version":{"type":["string","null"]},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"derivedFromVersionId":{"type":["string","null"]},"changelog":{"anyOf":[{"$ref":"#/components/schemas/ChangeLogSchema"},{"type":"null"}]},"sourceId":{"type":"string"},"type":{"$ref":"#/components/schemas/DigitalTwinTypeEnum"},"inputFields":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaEntryModelSchema"}},{"type":"null"}]},"temporalDependencies":{"anyOf":[{"$ref":"#/components/schemas/TemporalDependenciesSchema"},{"type":"null"}]},"timeSeriesMetadata":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesMetadataSchema"},{"type":"null"}]},"granularity":{"type":["string","null"]},"fixedSubGraph":{"anyOf":[{"$ref":"#/components/schemas/FixedSubGraphSchema"},{"type":"null"}]},"variableRoles":{"anyOf":[{"$ref":"#/components/schemas/VariableRolesSchema"},{"type":"null"}]},"derivedColumns":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/DtDerivedColumnInfoSchema"}},{"type":"null"}]},"dataSignature":{"type":"string"},"configSignature":{"type":"string"},"nTrainSamples":{"type":["number","null"]},"causalGraph":{"type":"array","items":{"$ref":"#/components/schemas/CausalRelationshipSchema"}},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/CausalNodeSchema"}},"evaluation":{"anyOf":[{"$ref":"#/components/schemas/EvaluationResultSchema"},{"type":"null"}]},"panelEvaluation":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/EvaluationResultSchema"}},{"type":"null"}]},"graphRecommendations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/GraphRecommendationsSchema"}},{"type":"null"}]},"environmentColumns":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"selectedEnvironmentColumns":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"selectedTimeColumnName":{"type":["string","null"]},"environmentSelection":{"anyOf":[{"$ref":"#/components/schemas/EnvironmentSelectionSchema"},{"type":"null"}]},"extraOps":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/OperationSchema"}},{"type":"null"}]},"nEnvironments":{"type":["number","null"]},"latentClusters":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/LatentClusterInfoSchema"}},{"type":"null"}]},"latentDiscoveryConfig":{"anyOf":[{"$ref":"#/components/schemas/LatentDiscoveryConfigSchema"},{"type":"null"}]},"nodeDomains":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"]}},{"type":"null"}]},"lastTimestampMs":{"type":["number","null"]},"headCommit":{"anyOf":[{"type":"integer"},{"type":"null"}]},"trainedWindowSignature":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]},"trainedWindowProfile":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ColumnWindowProfileSchema"}},{"type":"null"}]},"resolvedInputs":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"datasetId":{"type":"string"},"versionId":{"type":["string","null"]},"deltaVersion":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["datasetId"]}},{"type":"null"}]},"updateEligibility":{"anyOf":[{"type":"object","properties":{"updateMode":{"type":"string","enum":["assimilable","retrain_required","up_to_date","unsupported"]},"reasons":{"type":"array","items":{"type":"string"},"default":[]},"newRows":{"type":["number","null"]},"fromTsMs":{"type":["number","null"]},"toTsMs":{"type":["number","null"]},"historyDiff":{"anyOf":[{"$ref":"#/components/schemas/HistoryDiffSchema"},{"type":"null"}]}},"required":["updateMode"]},{"type":"null"}]},"trainingStages":{"anyOf":[{"type":"object","properties":{"confounderModelling":{"type":"boolean"},"equationDiscovery":{"type":"boolean"},"lagScreening":{"type":["boolean","null"]},"evalHorizons":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/EvalHorizonSchema"}},{"type":"null"}]}},"required":["confounderModelling","equationDiscovery"]},{"type":"null"}]},"timeComponent":{"anyOf":[{"$ref":"#/components/schemas/TimeComponentArtifactSchema"},{"type":"null"}]},"causalAlgorithmVersion":{"type":["string","null"]},"digitalTwinAlgorithmVersion":{"type":["string","null"]},"shardCount":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"maxLag":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"layout":{"anyOf":[{"type":"object","properties":{"success":{"type":"boolean"},"positions":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},{"type":"null"}]},"edgeWaypoints":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},{"type":"null"}]}},"required":["success"]},{"type":"null"}]},"lifecycleState":{"$ref":"#/components/schemas/LifecycleStateEnum","default":"created"},"currentTaskId":{"type":["string","null"]},"failureContext":{"anyOf":[{"$ref":"#/components/schemas/FailureContextSchema"},{"type":"null"}]},"traces":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"start":{"type":["string","null"]},"end":{"type":["string","null"]},"name":{"type":["string","null"]}}}},{"type":"null"}]},"arrayFeatureMap":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"arrayFeatureToBase":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]}},"required":["id","twinId","organisationId","workspaceId","versionMajor","versionMinor","versionPatch","sourceId","type","dataSignature","configSignature","causalGraph","nodes"]}]},"ChangeLogSchema":{"type":"object","properties":{"temporalDependenciesDiffs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TemporalDependencyChangeSchema"}},{"type":"null"}]},"fixedSubGraphDiffs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/FixedSubGraphChangeSchema"}},{"type":"null"}]},"causalGraphDiffs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/CausalGraphChangeSchema"}},{"type":"null"}]},"nodesDiffs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/NodeChangeSchema"}},{"type":"null"}]},"evaluationDiffs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/EvaluationChangeSchema"}},{"type":"null"}]}}},"TemporalDependencyChangeSchema":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ChangeTypeEnum"},"variable":{"type":"string"},"oldPrerequisites":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"newPrerequisites":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["type","variable"]},"ChangeTypeEnum":{"type":"string","enum":["added","removed","modified"]},"FixedSubGraphChangeSchema":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ChangeTypeEnum"},"changeTarget":{"type":"string","enum":["relationships","antiRelationships"]},"relationship":{"$ref":"#/components/schemas/CausalRelationshipSchema"}},"required":["type","changeTarget","relationship"]},"CausalRelationshipSchema":{"type":"object","properties":{"source":{"type":"string"},"target":{"type":"string"},"strength":{"type":"number"},"strengthStatus":{"anyOf":[{"type":"string","enum":["measured","not_measured"]},{"type":"null"}]},"timeLagEffects":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"lag":{"type":"number"},"strength":{"type":"number"},"granularity":{"type":["string","null"]}},"required":["lag","strength"]}},{"type":"null"}]},"cyclicalEffects":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"frequency":{"type":"string"},"strength":{"type":"number"}},"required":["frequency","strength"]}},{"type":"null"}]},"confidence":{"type":["number","null"]},"agreementRate":{"type":["number","null"]},"isEnvironmentGated":{"type":"boolean","default":false}},"required":["source","target","strength"]},"CausalGraphChangeSchema":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ChangeTypeEnum"},"relationship":{"$ref":"#/components/schemas/CausalRelationshipSchema"},"oldRelationship":{"anyOf":[{"$ref":"#/components/schemas/CausalRelationshipSchema"},{"type":"null"}]}},"required":["type","relationship"]},"NodeChangeSchema":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ChangeTypeEnum"},"node":{"$ref":"#/components/schemas/CausalNodeSchema"},"oldNode":{"anyOf":[{"$ref":"#/components/schemas/CausalNodeSchema"},{"type":"null"}]}},"required":["type","node"]},"CausalNodeSchema":{"type":"object","properties":{"name":{"type":"string"},"nodeType":{"$ref":"#/components/schemas/NodeTypeEnum","default":"observed"},"type":{"$ref":"#/components/schemas/SchemaMainTypeEnum"},"categories":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"latentClusterId":{"type":["number","null"]},"environmentColumns":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"isDerived":{"type":"boolean","default":false},"symbolicEquation":{"anyOf":[{"$ref":"#/components/schemas/SymbolicEquationSchema"},{"type":"null"}]},"derivedInfo":{"anyOf":[{"$ref":"#/components/schemas/DtDerivedColumnInfoSchema"},{"type":"null"}]},"parentImpacts":{"anyOf":[{"$ref":"#/components/schemas/NodeParentImpactsSchema"},{"type":"null"}],"description":"Model-based driver contribution shares computed after training"}},"required":["name","type"]},"NodeTypeEnum":{"type":"string","enum":["observed","latent","latent_inter","latent_intra","environment"]},"SchemaMainTypeEnum":{"type":"string","enum":["None","String","Category","Number","Boolean","DateTime","Array","Unknown"]},"SymbolicEquationSchema":{"type":"object","properties":{"expression":{"type":"string"},"r2":{"type":"number"},"noisePercentage":{"type":"number"},"termBreakdown":{"type":"array","items":{"$ref":"#/components/schemas/SymbolicTermSchema"}},"complexity":{"type":"number"},"explanationType":{"type":"string","enum":["regression","classification_rules","conditional_probability"],"default":"regression"},"epsilonSigma":{"type":["number","null"]},"epsilonSigmaRelative":{"type":["number","null"]},"expressionWithNoise":{"type":["string","null"]},"discoveryMethod":{"type":["string","null"]},"parentContributions":{"type":"array","items":{"$ref":"#/components/schemas/SymbolicParentContributionSchema"}},"unexplainedPct":{"type":["number","null"]},"directionReferenceClass":{"type":["string","null"]},"alternatives":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SymbolicEquationAlternativeSchema"}},{"type":"null"}],"description":"Pareto-front alternatives to the chosen equation (balanced / fewer terms / better fit); absent until discovery emits them"}},"required":["expression","r2","noisePercentage","termBreakdown","complexity"]},"SymbolicTermSchema":{"type":"object","properties":{"expression":{"type":"string"},"parentVariable":{"type":["string","null"]},"parentVariables":{"type":"array","items":{"type":"string"}},"coefficient":{"type":"number"},"operator":{"type":"string"},"contributionPercentage":{"type":"number"}},"required":["expression","coefficient","operator","contributionPercentage"]},"SymbolicParentContributionSchema":{"type":"object","properties":{"parent":{"type":"string"},"contributionPct":{"type":"number"},"signedEffect":{"type":"number"},"direction":{"type":"string","enum":["positive","negative","mixed","none"]},"terms":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["included","noEffect"]}},"required":["parent","contributionPct","signedEffect","direction","terms","status"]},"SymbolicEquationAlternativeSchema":{"type":"object","properties":{"label":{"type":"string","description":"How this alternative trades off, e.g. 'Balanced', 'Fewer terms', 'Better fit'"},"expression":{"type":"string"},"r2":{"type":["number","null"]},"complexity":{"type":["number","null"]}},"required":["label","expression"]},"DtDerivedColumnInfoSchema":{"type":"object","properties":{"derivedType":{"type":"string"},"targetColumn":{"type":"string"},"sourceColumns":{"type":"array","items":{"type":"string"}},"expression":{"type":"string"},"r2":{"type":["number","null"]},"isDeterministic":{"type":"boolean"},"implausibilityReason":{"type":["string","null"]},"lag":{"type":["number","null"]},"cumulativeDirection":{"type":["string","null"]},"seasonalTerms":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SeasonalTermSchema"}},{"type":"null"}]},"isMonotonicallyIncreasing":{"type":["boolean","null"]},"isMonotonicallyDecreasing":{"type":["boolean","null"]}},"required":["derivedType","targetColumn","sourceColumns","expression","isDeterministic"]},"SeasonalTermSchema":{"type":"object","properties":{"period":{"type":"number"},"order":{"type":"number","default":1}},"required":["period"]},"NodeParentImpactsSchema":{"type":"object","properties":{"node":{"type":"string"},"method":{"type":"string","enum":["forecast_attribution","fwl_betas","gaamt_betas","cat_logit_betas","do_contrast"]},"parents":{"type":"array","items":{"$ref":"#/components/schemas/ParentImpactEntrySchema"}},"exogenous":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ParentImpactEntrySchema"}},{"type":"null"}],"description":"Trend/seasonal/level drivers on the same 0-100 scale as parents"},"nonParentShare":{"type":["number","null"]}},"required":["node","method","parents"]},"ParentImpactEntrySchema":{"type":"object","properties":{"parent":{"type":"string"},"impactPct":{"type":"number","description":"Share of total driver influence on the node, 0-100"},"signedEffect":{"type":"number"},"lagBreakdown":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}]}},"required":["parent","impactPct","signedEffect"]},"EvaluationChangeSchema":{"type":"object","properties":{"type":{"type":"string","enum":["improvement","worsening"]},"metric":{"type":"string"},"oldValue":{"type":["number","null"]},"newValue":{"type":"number"},"percentChange":{"type":["number","null"]}},"required":["type","metric","newValue"]},"DigitalTwinTypeEnum":{"type":"string","enum":["static","temporal","multi-environment-temporal","multi-environment-static"]},"SchemaEntryModelSchema":{"type":"object","properties":{"field":{"type":"string"},"type":{"$ref":"#/components/schemas/SchemaMainTypeEnum"},"subtype":{"anyOf":[{"$ref":"#/components/schemas/SchemaSubTypeEnum"},{"type":"null"}]},"availableTypes":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaMainTypeEnum"}},{"type":"null"}]},"isIndex":{"type":["boolean","null"]},"categories":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"aliases":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"description":{"type":["string","null"]},"displayWidth":{"type":["number","null"]},"originalFormat":{"type":["string","null"]},"displayFormat":{"type":["string","null"]},"unit":{"type":["string","null"]},"unitModifier":{"type":["number","null"]},"dateOrderAssumed":{"type":["boolean","null"]}},"required":["field","type"]},"SchemaSubTypeEnum":{"type":"string","enum":["Integer","Float","UnsignedInteger","UnsignedFloat","String","Number","Category","Boolean","DateTime"]},"TemporalDependenciesSchema":{"anyOf":[{"not":{}},{"anyOf":[{"$ref":"#/components/schemas/TemporalDependenciesObjectSchema"},{"type":"null"}]}]},"TemporalDependenciesObjectSchema":{"type":"object","properties":{"prerequisites":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["prerequisites"]},"TimeSeriesMetadataSchema":{"type":"object","properties":{"colName":{"type":"string","description":"Column name for the time series"},"granularity":{"type":"string","enum":["ms","s","min","h","D","W","ME","Y","L","S","T","H"],"description":"Current granularity of the time series"},"validGranularities":{"type":"array","items":{"type":"string"},"description":"List of valid granularities"},"startDate":{"type":"string","description":"Start date of the time series"},"endDate":{"type":"string","description":"End date of the time series"},"typicalDeltaSeconds":{"type":["number","null"]},"selectedGrid":{"type":["string","null"]},"candidateGrids":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"scoring":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"number"}}},{"type":"null"}]},"coverage":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesCoverageSchema"},{"type":"null"}],"description":"Observed vs imputed grid steps; absent on twins trained before this existed"}},"required":["colName","granularity","validGranularities","startDate","endDate"]},"TimeSeriesCoverageSchema":{"type":"object","properties":{"observedSteps":{"type":"number","description":"Grid steps that carried at least one observed row"},"gridSteps":{"type":"number","description":"Steps on the dense grid the twin trains on"},"imputedSteps":{"type":"number","description":"Grid steps reconstructed by imputation, never measured"},"gapCount":{"type":"number","description":"Total gap runs; `gaps` lists only the largest"},"gaps":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesGapSchema"}}},"required":["observedSteps","gridSteps","imputedSteps","gapCount","gaps"]},"TimeSeriesGapSchema":{"type":"object","properties":{"startDate":{"type":"string","description":"First grid step in the gap"},"endDate":{"type":"string","description":"Last grid step in the gap"},"missingSteps":{"type":"number","description":"Consecutive grid steps with no observed rows"}},"required":["startDate","endDate","missingSteps"]},"FixedSubGraphSchema":{"type":"object","properties":{"relationships":{"type":"array","items":{"$ref":"#/components/schemas/CausalRelationshipSchema"}},"antiRelationships":{"type":"array","items":{"$ref":"#/components/schemas/CausalRelationshipSchema"}}},"required":["relationships","antiRelationships"]},"VariableRolesSchema":{"type":"object","properties":{"sources":{"type":"array","items":{"type":"string"}},"targets":{"type":"array","items":{"type":"string"}}},"required":["sources","targets"]},"EvaluationResultSchema":{"type":"object","properties":{"modelType":{"type":"string","enum":["cbn","tcbn"],"description":"Type of the model"},"nodeMetrics":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/NodeMetricsSchema"},"description":"Metrics for each node"},"globalMetrics":{"type":"object","properties":{"logLikelihood":{"type":["number","null"],"description":"Overall log-likelihood"},"averageMse":{"type":["number","null"],"description":"Overall mean squared error"},"averageMae":{"type":["number","null"],"description":"Overall mean absolute error"},"averageAccuracy":{"type":["number","null"],"description":"Overall accuracy"},"averageMape":{"type":["number","null"],"description":"Overall mean absolute percentage error"}},"description":"Global metrics"},"skippedReason":{"anyOf":[{"type":"string","enum":["insufficient_data"]},{"type":"null"}],"description":"Set when evaluation was deliberately skipped"},"skipReasons":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"User-facing explanation of why evaluation was skipped"},"nEvalPoints":{"type":["number","null"],"description":"Number of holdout time steps evaluation used (or would have used)"}},"required":["modelType","nodeMetrics","globalMetrics"]},"NodeMetricsSchema":{"type":"object","properties":{"accuracy":{"type":["number","null"],"description":"Classification accuracy"},"accuracyPerClass":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}],"description":"Classification accuracy per class"},"weightedAccuracy":{"type":["number","null"],"description":"Weighted classification accuracy"},"falsePositiveRate":{"type":["number","null"],"description":"False positive rate"},"falseNegativeRate":{"type":["number","null"],"description":"False negative rate"},"truePositiveRate":{"type":["number","null"],"description":"True positive rate"},"trueNegativeRate":{"type":["number","null"],"description":"True negative rate"},"precision":{"type":["number","null"],"description":"Precision, macro-averaged across classes"},"recall":{"type":["number","null"],"description":"Recall, macro-averaged across classes"},"f1Score":{"type":["number","null"],"description":"F1 score, macro-averaged across classes"},"precisionPerClass":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}],"description":"Precision per class"},"recallPerClass":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}],"description":"Recall per class"},"f1ScorePerClass":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}],"description":"F1 score per class"},"positiveClassLabel":{"type":["string","null"],"description":"Decoded label of encoded class 1, the anchor for TPR/FPR/TNR/FNR"},"mse":{"type":["number","null"],"description":"Mean squared error"},"r2":{"type":["number","null"],"description":"R-squared"},"logLikelihood":{"type":["number","null"],"description":"Log-likelihood"},"auc":{"type":["number","null"],"description":"Area under ROC curve"},"brierScore":{"type":["number","null"],"description":"Brier score"},"mae":{"type":["number","null"],"description":"Mean absolute error"},"mape":{"anyOf":[{"type":"object","additionalProperties":{"type":["number","null"]}},{"type":"null"}],"description":"Mean absolute percentage error per horizon"}}},"GraphRecommendationsSchema":{"type":"object","properties":{"x":{"type":"string"},"y":{"type":"string"},"direction":{"type":"string","enum":["forward","backward"]},"reasons":{"type":"array","items":{"type":"string"}}},"required":["x","y","direction","reasons"]},"EnvironmentSelectionSchema":{"type":"object","properties":{"baseline":{"type":"string","enum":["all","none"]},"exceptions":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"required":["baseline","exceptions"]},"OperationSchema":{"type":"object","properties":{"id":{"type":"string"},"sourceId":{"type":"string"},"config":{"$ref":"#/components/schemas/OperationConfigSchema"}},"required":["id","sourceId","config"]},"OperationConfigSchema":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"FILTER"},"filterGroup":{"anyOf":[{"$ref":"#/components/schemas/FilterSchema"},{"$ref":"#/components/schemas/FilterGroupSchema"}]}},"required":["type","filterGroup"]},{"type":"object","properties":{"type":{"type":"string","const":"AGGREGATE"},"groupByColumns":{"type":"array","items":{"type":"string"}},"aggregations":{"type":"array","items":{"$ref":"#/components/schemas/AggregationFunctionSchema"}}},"required":["type","groupByColumns","aggregations"]},{"type":"object","properties":{"type":{"type":"string","const":"JOIN"},"joinType":{"$ref":"#/components/schemas/JoinTypeEnum"},"columnPairs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/JoinColumnPairSchema"}},{"type":"null"}]},"leftField":{"type":["string","null"]},"rightField":{"type":["string","null"]},"conflictResolution":{"$ref":"#/components/schemas/JoinConflictResolutionEnum"},"leftPrefix":{"type":["string","null"]},"rightPrefix":{"type":["string","null"]}},"required":["type","joinType","conflictResolution"]},{"type":"object","properties":{"type":{"type":"string","const":"CONCATENATE"},"topSource":{"type":["string","null"]},"bottomSource":{"type":["string","null"]},"sources":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"columnMapping":{"type":"object","additionalProperties":{"type":"string"}},"unmatchedRule":{"$ref":"#/components/schemas/UnmatchedRuleEnum"},"discriminatorColumn":{"type":["string","null"]},"discriminatorValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]}},"required":["type","columnMapping","unmatchedRule"]},{"type":"object","properties":{"type":{"type":"string","const":"SORT"},"sortColumns":{"type":"array","items":{"$ref":"#/components/schemas/SortColumnSchema"}}},"required":["type","sortColumns"]},{"type":"object","properties":{"type":{"type":"string","const":"SQL_QUERY"},"query":{"type":"string"},"columnSourceAliases":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]}},"required":["type","query"]},{"type":"object","properties":{"type":{"type":"string","const":"SPLIT_COLUMN"},"columnToSplit":{"type":"string"},"splitType":{"$ref":"#/components/schemas/SplitTypeEnum"},"delimiter":{"type":["string","null"]},"columns":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/NewColumnDefinitionSchema"}},{"type":"null"}]}},"required":["type","columnToSplit","splitType"]},{"type":"object","properties":{"type":{"type":"string","const":"DROP_COLUMNS"},"columns":{"type":"array","items":{"type":"string"}}},"required":["type","columns"]},{"type":"object","properties":{"type":{"type":"string","const":"REMOVE_DUPLICATES"},"column":{"type":["string","null"]},"keep":{"$ref":"#/components/schemas/KeepEnum","default":"first"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"IMPUTE_NULLS"},"method":{"$ref":"#/components/schemas/ImputeMethodEnum","default":"constant"},"column":{"type":["string","null"]},"fillValue":{"anyOf":[{"type":["string","number","boolean"]},{"type":"null"}]},"imputations":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"column":{"type":"string"},"method":{"$ref":"#/components/schemas/ImputeMethodEnum","default":"constant"},"fillValue":{"anyOf":[{"type":["string","number","boolean"]},{"type":"null"}]}},"required":["column"]}},{"type":"null"}]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"DROP_NULLS"},"axis":{"type":"string","enum":["rows","empty_columns"],"default":"rows"},"column":{"type":["string","null"]},"columns":{"type":"array","items":{"type":"string"},"default":[]},"nullThresholdPercent":{"type":"number","default":100}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"REPLACE_VALUES"},"column":{"type":"string"},"mapping":{"type":"object","additionalProperties":{"type":["string","null"]}}},"required":["type","column","mapping"]},{"type":"object","properties":{"type":{"type":"string","const":"REPLACE_TYPE"},"changes":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"column":{"type":"string"},"toType":{"$ref":"#/components/schemas/SchemaMainTypeEnum"},"toSubType":{"anyOf":[{"$ref":"#/components/schemas/SchemaSubTypeEnum"},{"type":"null"}]},"dateFormat":{"type":["string","null"]}},"required":["column","toType"]}},{"type":"null"}]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"INTERPOLATE_TIME"},"column":{"type":"string"},"frequency":{"type":"string"},"method":{"$ref":"#/components/schemas/InterpolateTimeMethodEnum"}},"required":["type","column","frequency","method"]},{"type":"object","properties":{"type":{"type":"string","const":"CLIP_OUTLIERS"},"column":{"type":"string"},"lowerQuantile":{"type":"number","default":0.05},"upperQuantile":{"type":"number","default":0.95}},"required":["type","column"]},{"type":"object","properties":{"type":{"type":"string","const":"NORMALIZE_NUMERIC"},"column":{"type":"string"},"method":{"$ref":"#/components/schemas/NormalizeNumericMethodEnum","default":"z_score"}},"required":["type","column"]},{"type":"object","properties":{"type":{"type":"string","const":"MAP_CATEGORIES"},"column":{"type":"string"},"mapping":{"type":"object","additionalProperties":{"type":"string"}},"defaultValue":{"type":["string","null"]}},"required":["type","column","mapping"]},{"type":"object","properties":{"type":{"type":"string","const":"TIME_SERIES_AGGREGATE"},"timeColumn":{"type":"string"},"granularity":{"type":"string","enum":["nanosecond","microsecond","millisecond","second","minute","hour","day","week","month","quarter","year"]},"aggregations":{"type":"array","items":{"$ref":"#/components/schemas/AggregationFunctionSchema"}},"dateFormat":{"anyOf":[{"$ref":"#/components/schemas/DatetimeFormatSchema"},{"type":"null"}]}},"required":["type","timeColumn","granularity","aggregations"]},{"type":"object","properties":{"type":{"type":"string","const":"TIME_SERIES_JOIN"},"joinType":{"$ref":"#/components/schemas/JoinTypeEnum"},"leftTimeColumn":{"type":"string"},"rightTimeColumn":{"type":"string"},"rightSource":{"type":"string"},"strategy":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"exact"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"granularity"},"granularity":{"type":"string","enum":["nanosecond","microsecond","millisecond","second","minute","hour","day","week","month","quarter","year"]}},"required":["type","granularity"]},{"type":"object","properties":{"type":{"type":"string","const":"asOf"},"direction":{"$ref":"#/components/schemas/AsOfDirectionEnum"},"tolerance":{"anyOf":[{"type":"object","properties":{"value":{"type":"number"},"unit":{"$ref":"#/components/schemas/ToleranceUnitEnum"}},"required":["value","unit"]},{"type":"null"}]}},"required":["type","direction"]},{"type":"object","properties":{"type":{"type":"string","const":"interval"},"leftEndColumn":{"type":"string"}},"required":["type","leftEndColumn"]}],"discriminator":{"propertyName":"type"}},"exactMatchKeys":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"leftField":{"type":"string"},"rightField":{"type":"string"}},"required":["leftField","rightField"]}},{"type":"null"}]},"multiMatch":{"$ref":"#/components/schemas/MultiMatchStrategyEnum"},"multiMatchAggregations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/AggregationFunctionSchema"}},{"type":"null"}]}},"required":["type","joinType","leftTimeColumn","rightTimeColumn","rightSource","strategy","multiMatch"]},{"type":"object","properties":{"type":{"type":"string","const":"TRANSPOSE"},"timeColumn":{"type":"string"},"envColumns":{"type":"array","items":{"type":"string"}},"valueColumns":{"type":"array","items":{"type":"string"}},"columnTemplate":{"type":"string"},"joinStrategy":{"anyOf":[{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"exact"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"granularity"},"granularity":{"type":"string","enum":["nanosecond","microsecond","millisecond","second","minute","hour","day","week","month","quarter","year"]}},"required":["type","granularity"]},{"type":"object","properties":{"type":{"type":"string","const":"asOf"},"direction":{"$ref":"#/components/schemas/AsOfDirectionEnum"},"tolerance":{"anyOf":[{"type":"object","properties":{"value":{"type":"number"},"unit":{"$ref":"#/components/schemas/ToleranceUnitEnum"}},"required":["value","unit"]},{"type":"null"}]}},"required":["type","direction"]}],"discriminator":{"propertyName":"type"}},{"type":"null"}]}},"required":["type","timeColumn","envColumns","valueColumns","columnTemplate"]},{"type":"object","properties":{"type":{"type":"string","const":"FREQUENCY_ANALYSIS"},"timeColumn":{"type":"string"},"valueColumns":{"type":"array","items":{"type":"string"}},"method":{"$ref":"#/components/schemas/FrequencyMethodEnum"},"windowFunction":{"$ref":"#/components/schemas/FrequencyWindowFunctionEnum","default":"hann"},"windowSize":{"type":["number","null"]},"overlap":{"type":"number","default":0.5},"samplingRateHz":{"type":["number","null"]},"outputFormat":{"$ref":"#/components/schemas/FrequencyOutputFormatEnum"},"frequencyRange":{"anyOf":[{"type":"object","properties":{"minHz":{"type":["number","null"]},"maxHz":{"type":["number","null"]}}},{"type":"null"}]},"frequencyUnit":{"$ref":"#/components/schemas/FrequencyUnitEnum","default":"hz"}},"required":["type","timeColumn","valueColumns","method","outputFormat"]},{"type":"object","properties":{"type":{"type":"string","const":"CYCLIC_AGGREGATE"},"timeColumn":{"type":"string"},"cycleComponent":{"$ref":"#/components/schemas/CyclicComponentEnum"},"aggregations":{"type":"array","items":{"$ref":"#/components/schemas/AggregationFunctionSchema"}}},"required":["type","timeColumn","cycleComponent","aggregations"]},{"type":"object","properties":{"type":{"type":"string","const":"DIFF"},"timeColumn":{"type":"string"},"columns":{"type":"array","items":{"type":"string"}},"partitionColumns":{"type":"array","items":{"type":"string"},"default":[]},"outputSuffix":{"type":"string","default":"_diff"},"replaceColumns":{"type":"boolean","default":false}},"required":["type","timeColumn","columns"]},{"type":"object","properties":{"type":{"type":"string","const":"DATE_DIFF"},"startColumn":{"type":"string"},"endColumn":{"type":"string"},"unit":{"$ref":"#/components/schemas/DateDiffUnitEnum","default":"days"},"sign":{"$ref":"#/components/schemas/DateDiffSignEnum","default":"signed"},"outputColumn":{"type":["string","null"]}},"required":["type","startColumn","endColumn"]},{"type":"object","properties":{"type":{"type":"string","const":"CUMULATIVE"},"timeColumn":{"type":"string"},"columns":{"type":"array","items":{"type":"string"}},"partitionColumns":{"type":"array","items":{"type":"string"},"default":[]},"outputSuffix":{"type":"string","default":"_cumsum"},"replaceColumns":{"type":"boolean","default":false}},"required":["type","timeColumn","columns"]},{"type":"object","properties":{"type":{"type":"string","const":"ARRAY_DECOMPOSE"},"column":{"type":"string"},"mode":{"$ref":"#/components/schemas/ArrayDecomposeModeEnum","default":"position"},"maxColumns":{"type":"integer","exclusiveMinimum":0,"default":500},"outputPrefix":{"type":"string","default":"_"}},"required":["type","column"]},{"type":"object","properties":{"type":{"type":"string","const":"ARRAY_CONSOLIDATE"},"groups":{"type":"array","items":{"type":"object","properties":{"columns":{"type":"array","items":{"type":"string"},"minItems":1},"outputColumn":{"type":"string"},"dropSource":{"type":"boolean","default":true},"includeNulls":{"type":"boolean","default":false}},"required":["columns","outputColumn"]},"minItems":1}},"required":["type","groups"]},{"type":"object","properties":{"type":{"type":"string","const":"ARRAY_EXPLODE"},"column":{"type":"string"},"outputColumn":{"type":["string","null"]},"preserveIndex":{"type":"boolean","default":false}},"required":["type","column"]},{"type":"object","properties":{"type":{"type":"string","const":"ARRAY_AGGREGATE"},"column":{"type":"string"},"aggregation":{"$ref":"#/components/schemas/ArrayAggregationKindEnum"},"outputColumn":{"type":["string","null"]}},"required":["type","column","aggregation"]},{"type":"object","properties":{"type":{"type":"string","const":"JSON_FLATTEN"},"column":{"type":"string"},"maxColumns":{"type":"integer","exclusiveMinimum":0,"default":500},"separator":{"type":"string","default":"."},"dropSource":{"type":"boolean","default":true}},"required":["type","column"]}],"discriminator":{"propertyName":"type"}},"FilterSchema":{"type":"object","properties":{"column":{"type":"string"},"comparisonOperator":{"$ref":"#/components/schemas/ComparisonOperatorEnum"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":["string","number","boolean"]}}]},"correctType":{"type":"boolean"}},"required":["column","comparisonOperator","value","correctType"]},"ComparisonOperatorEnum":{"type":"string","enum":["Equal to","Not Equal to","Contains","Does not contain","Starts with","Ends with","Is Empty","Is not Empty","Less than","Greater than","Less than or equal to","Greater than or equal to","Before","After","Array contains","Array contains any","Array contains all","Array does not contain","Array does not contain any","Array does not contain all","Array size equal to","Array size greater than","Array size less than"]},"FilterGroupSchema":{"type":"object","properties":{"booleanOperator":{"$ref":"#/components/schemas/LogicalOperatorEnum"},"filters":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/FilterSchema"},{"$ref":"#/components/schemas/FilterGroupSchema"}]}}},"required":["booleanOperator","filters"]},"LogicalOperatorEnum":{"type":"string","enum":["AND","OR"]},"AggregationFunctionSchema":{"type":"object","properties":{"column":{"type":"string"},"function":{"$ref":"#/components/schemas/AggregateFunctionEnum"},"alias":{"type":["string","null"]},"filter":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/FilterSchema"},{"$ref":"#/components/schemas/FilterGroupSchema"}]},{"type":"null"}]}},"required":["column","function"]},"AggregateFunctionEnum":{"type":"string","enum":["sum","avg","min","max","count","countDistinct","first","last","categoryShare"]},"JoinTypeEnum":{"type":"string","enum":["inner","left","right","full"]},"JoinColumnPairSchema":{"type":"object","properties":{"leftField":{"type":"string"},"rightField":{"type":"string"}},"required":["leftField","rightField"]},"JoinConflictResolutionEnum":{"type":"string","enum":["keep_left","keep_right","prefix"]},"UnmatchedRuleEnum":{"type":"string","enum":["error","drop","append"]},"SortColumnSchema":{"type":"object","properties":{"column":{"type":"string"},"direction":{"$ref":"#/components/schemas/SortDirectionEnum"}},"required":["column","direction"]},"SortDirectionEnum":{"type":"string","enum":["asc","desc"]},"SplitTypeEnum":{"type":"string","enum":["delimiter","pattern"]},"NewColumnDefinitionSchema":{"type":"object","properties":{"name":{"type":"string"},"pattern":{"type":["string","null"]}},"required":["name"]},"KeepEnum":{"type":"string","enum":["first","last"]},"ImputeMethodEnum":{"type":"string","enum":["mean","median","mode","constant"]},"InterpolateTimeMethodEnum":{"type":"string","enum":["linear","time","index"]},"NormalizeNumericMethodEnum":{"type":"string","enum":["min_max","z_score"]},"DatetimeFormatSchema":{"type":"string","minLength":1},"AsOfDirectionEnum":{"type":"string","enum":["backward","forward","nearest"]},"ToleranceUnitEnum":{"type":"string","enum":["us","ms","s","m","h","d"]},"MultiMatchStrategyEnum":{"type":"string","enum":["first","last","aggregate"]},"FrequencyMethodEnum":{"type":"string","enum":["fft","welch"]},"FrequencyWindowFunctionEnum":{"type":"string","enum":["hann","hamming","blackman","rectangular"]},"FrequencyOutputFormatEnum":{"type":"string","enum":["spectrogram","time_frequency_long"]},"FrequencyUnitEnum":{"type":"string","enum":["hz","per_minute","per_hour","per_day","per_week","per_month","per_year"]},"CyclicComponentEnum":{"type":"string","enum":["second_in_minute","minute_in_hour","hour_of_day","day_of_week","day_of_month","week_of_year","month_of_year","quarter_of_year"]},"DateDiffUnitEnum":{"type":"string","enum":["seconds","minutes","hours","days","weeks"]},"DateDiffSignEnum":{"type":"string","enum":["signed","absolute"]},"ArrayDecomposeModeEnum":{"type":"string","enum":["position","one_hot"]},"ArrayAggregationKindEnum":{"type":"string","enum":["mean","sum","min","max","median","count"]},"LatentClusterInfoSchema":{"type":"object","properties":{"clusterId":{"type":"number"},"affectedNodes":{"type":"array","items":{"type":"string"}},"estimatedDim":{"type":"number","default":1},"dicSatisfied":{"type":"boolean","default":true},"interColumnNames":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"intraColumnNames":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"modelStatus":{"anyOf":[{"$ref":"#/components/schemas/LatentModelStatusEnum"},{"type":"null"}]},"modelFailureReason":{"anyOf":[{"$ref":"#/components/schemas/LatentFitFailureReasonEnum"},{"type":"null"}]},"modelFailureDetail":{"type":["string","null"]},"avgLcScore":{"type":["number","null"]},"reconstructionError":{"type":["number","null"]},"envPredictability":{"type":["number","null"]},"memberLatentShare":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}]},"seasonalStrength":{"type":["number","null"]}},"required":["clusterId","affectedNodes"]},"LatentModelStatusEnum":{"type":"string","enum":["modelled","detectedOnly"]},"LatentFitFailureReasonEnum":{"type":"string","enum":["tooFewMembers","noNumericMembers","noExternalParents","allParentColumnsEmpty","insufficientCleanRows","fitError"]},"LatentDiscoveryConfigSchema":{"type":"object","properties":{"enabled":{"type":"boolean","default":true},"residualCorrelationThreshold":{"type":"number","default":0.3},"ciTestAlpha":{"type":"number","default":0.05},"minClusterSize":{"type":"number","default":2},"maxLatentDim":{"type":"number","default":5}}},"ColumnWindowProfileSchema":{"type":"object","properties":{"count":{"type":["number","null"]},"distinct":{"type":["number","null"]},"min":{"type":["string","null"]},"max":{"type":["string","null"]}}},"HistoryDiffSchema":{"type":"object","properties":{"changedColumns":{"type":"array","items":{"type":"object","properties":{"column":{"type":"string"},"stored":{"anyOf":[{"$ref":"#/components/schemas/ColumnWindowProfileSchema"},{"type":"null"}]},"current":{"anyOf":[{"$ref":"#/components/schemas/ColumnWindowProfileSchema"},{"type":"null"}]}},"required":["column"]},"default":[]},"deltaOperations":{"type":"array","items":{"type":"object","properties":{"datasetId":{"type":"string"},"version":{"type":"integer"},"operation":{"type":"string"},"timestampMs":{"type":["number","null"]}},"required":["datasetId","version","operation"]},"default":[]},"rewrittenDatasets":{"type":"array","items":{"type":"string"},"default":[]}}},"EvalHorizonSchema":{"type":"object","properties":{"count":{"type":"integer","exclusiveMinimum":0},"unit":{"$ref":"#/components/schemas/HorizonUnitEnum"}},"required":["count","unit"]},"HorizonUnitEnum":{"type":"string","enum":["S","T","H","D","W","ME","Y"]},"TimeComponentArtifactSchema":{"type":"object","properties":{"models":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimeDecompositionModelSchema"}},"varExplained":{"type":"object","additionalProperties":{"type":"number"}},"trainNSamples":{"type":"number"}},"required":["models","varExplained","trainNSamples"]},"TimeDecompositionModelSchema":{"type":"object","properties":{"theilSenSlope":{"type":"number"},"theilSenIntercept":{"type":"number"},"harmonic":{"anyOf":[{"$ref":"#/components/schemas/HarmonicFitSchema"},{"type":"null"}]}},"required":["theilSenSlope","theilSenIntercept"]},"HarmonicFitSchema":{"type":"object","properties":{"periodsWithHarmonics":{"type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}]}},"sinCosCoefficients":{"type":"array","items":{"type":"number"}},"productPairs":{"type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}]}},"productCoefficients":{"type":"array","items":{"type":"number"}}},"required":["periodsWithHarmonics","sinCosCoefficients","productPairs","productCoefficients"]},"LifecycleStateEnum":{"type":"string","enum":["created","discovering","resolved","training","trained","failed","cancelled"]},"FailureContextSchema":{"type":"object","properties":{"error":{"type":"string"},"failedAtStage":{"type":"string","enum":["causal_discovery","model_training"]},"retryable":{"type":"boolean","default":true},"userFacing":{"type":"boolean","default":false}},"required":["error","failedAtStage"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-versions","summary":"List versions","description":"Lists all versions of this digital twin. Paginated (limit, cursor). Read from platform MongoDB (digitalTwinVersion collection). Versions carry lifecycleState, causalGraph, and the data they model as datasetId (a derived dataset) or sourceId (a raw source) — whichever the twin was created with.","tags":["Digital Twins"],"parameters":[{"in":"query","name":"limit","required":false,"schema":{"description":"Page size (1-1000, default 50).","type":"number","minimum":1,"maximum":1000},"description":"Page size (1-1000, default 50)."},{"in":"query","name":"cursor","required":false,"schema":{"type":"string","description":"Opaque cursor from a previous response's `pagination.cursor`."},"description":"Opaque cursor from a previous response's `pagination.cursor`."},{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DigitalTwinVersionListEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Create version

> Derives a new version from an existing one — the retrain primitive. Body (all optional): bump (major | minor | patch, default patch), baseVersionId (default: the latest version), datasetId (point the new version at different data). The new version inherits the base's configuration and causal graph, resets all training outputs, and lands in lifecycleState resolved — train it with POST .../versions/{vId}/train. Version numbers never collide: the bumped component skips past any label already taken.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"CreateVersionInput":{"type":"object","properties":{"bump":{"type":"string","enum":["major","minor","patch"],"default":"patch","description":"Which version component to bump (default patch)"},"baseVersionId":{"type":["string","null"],"description":"Version to derive from; the latest version when omitted"},"datasetId":{"type":["string","null"],"description":"Point the new version at a different dataset"}}},"DigitalTwinVersionEnvelope":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/DigitalTwinVersion"}},"required":["data"]},"DigitalTwinVersion":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"twinId":{"type":"string"},"organisationId":{"type":"string"},"workspaceId":{"type":"string"},"versionMajor":{"type":"number","minimum":0},"versionMinor":{"type":"number","minimum":0},"versionPatch":{"type":"number","minimum":0},"version":{"type":["string","null"]},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"derivedFromVersionId":{"type":["string","null"]},"changelog":{"anyOf":[{"$ref":"#/components/schemas/ChangeLogSchema"},{"type":"null"}]},"datasetId":{"type":"string"},"type":{"$ref":"#/components/schemas/DigitalTwinTypeEnum"},"inputFields":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaEntryModelSchema"}},{"type":"null"}]},"temporalDependencies":{"anyOf":[{"$ref":"#/components/schemas/TemporalDependenciesSchema"},{"type":"null"}]},"timeSeriesMetadata":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesMetadataSchema"},{"type":"null"}]},"granularity":{"type":["string","null"]},"fixedSubGraph":{"anyOf":[{"$ref":"#/components/schemas/FixedSubGraphSchema"},{"type":"null"}]},"variableRoles":{"anyOf":[{"$ref":"#/components/schemas/VariableRolesSchema"},{"type":"null"}]},"derivedColumns":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/DtDerivedColumnInfoSchema"}},{"type":"null"}]},"dataSignature":{"type":"string"},"configSignature":{"type":"string"},"nTrainSamples":{"type":["number","null"]},"causalGraph":{"type":"array","items":{"$ref":"#/components/schemas/CausalRelationshipSchema"}},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/CausalNodeSchema"}},"evaluation":{"anyOf":[{"$ref":"#/components/schemas/EvaluationResultSchema"},{"type":"null"}]},"panelEvaluation":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/EvaluationResultSchema"}},{"type":"null"}]},"graphRecommendations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/GraphRecommendationsSchema"}},{"type":"null"}]},"environmentColumns":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"selectedEnvironmentColumns":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"selectedTimeColumnName":{"type":["string","null"]},"environmentSelection":{"anyOf":[{"$ref":"#/components/schemas/EnvironmentSelectionSchema"},{"type":"null"}]},"extraOps":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/OperationSchema"}},{"type":"null"}]},"nEnvironments":{"type":["number","null"]},"latentClusters":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/LatentClusterInfoSchema"}},{"type":"null"}]},"latentDiscoveryConfig":{"anyOf":[{"$ref":"#/components/schemas/LatentDiscoveryConfigSchema"},{"type":"null"}]},"nodeDomains":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"]}},{"type":"null"}]},"lastTimestampMs":{"type":["number","null"]},"headCommit":{"anyOf":[{"type":"integer"},{"type":"null"}]},"trainedWindowSignature":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]},"trainedWindowProfile":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ColumnWindowProfileSchema"}},{"type":"null"}]},"resolvedInputs":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"datasetId":{"type":"string"},"versionId":{"type":["string","null"]},"deltaVersion":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["datasetId"]}},{"type":"null"}]},"updateEligibility":{"anyOf":[{"type":"object","properties":{"updateMode":{"type":"string","enum":["assimilable","retrain_required","up_to_date","unsupported"]},"reasons":{"type":"array","items":{"type":"string"},"default":[]},"newRows":{"type":["number","null"]},"fromTsMs":{"type":["number","null"]},"toTsMs":{"type":["number","null"]},"historyDiff":{"anyOf":[{"$ref":"#/components/schemas/HistoryDiffSchema"},{"type":"null"}]}},"required":["updateMode"]},{"type":"null"}]},"trainingStages":{"anyOf":[{"type":"object","properties":{"confounderModelling":{"type":"boolean"},"equationDiscovery":{"type":"boolean"},"lagScreening":{"type":["boolean","null"]},"evalHorizons":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/EvalHorizonSchema"}},{"type":"null"}]}},"required":["confounderModelling","equationDiscovery"]},{"type":"null"}]},"timeComponent":{"anyOf":[{"$ref":"#/components/schemas/TimeComponentArtifactSchema"},{"type":"null"}]},"causalAlgorithmVersion":{"type":["string","null"]},"digitalTwinAlgorithmVersion":{"type":["string","null"]},"shardCount":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"maxLag":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"layout":{"anyOf":[{"type":"object","properties":{"success":{"type":"boolean"},"positions":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},{"type":"null"}]},"edgeWaypoints":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},{"type":"null"}]}},"required":["success"]},{"type":"null"}]},"lifecycleState":{"$ref":"#/components/schemas/LifecycleStateEnum","default":"created"},"currentTaskId":{"type":["string","null"]},"failureContext":{"anyOf":[{"$ref":"#/components/schemas/FailureContextSchema"},{"type":"null"}]},"traces":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"start":{"type":["string","null"]},"end":{"type":["string","null"]},"name":{"type":["string","null"]}}}},{"type":"null"}]},"arrayFeatureMap":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"arrayFeatureToBase":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]}},"required":["id","twinId","organisationId","workspaceId","versionMajor","versionMinor","versionPatch","datasetId","type","dataSignature","configSignature","causalGraph","nodes"]},{"type":"object","properties":{"id":{"type":"string"},"twinId":{"type":"string"},"organisationId":{"type":"string"},"workspaceId":{"type":"string"},"versionMajor":{"type":"number","minimum":0},"versionMinor":{"type":"number","minimum":0},"versionPatch":{"type":"number","minimum":0},"version":{"type":["string","null"]},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"derivedFromVersionId":{"type":["string","null"]},"changelog":{"anyOf":[{"$ref":"#/components/schemas/ChangeLogSchema"},{"type":"null"}]},"sourceId":{"type":"string"},"type":{"$ref":"#/components/schemas/DigitalTwinTypeEnum"},"inputFields":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaEntryModelSchema"}},{"type":"null"}]},"temporalDependencies":{"anyOf":[{"$ref":"#/components/schemas/TemporalDependenciesSchema"},{"type":"null"}]},"timeSeriesMetadata":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesMetadataSchema"},{"type":"null"}]},"granularity":{"type":["string","null"]},"fixedSubGraph":{"anyOf":[{"$ref":"#/components/schemas/FixedSubGraphSchema"},{"type":"null"}]},"variableRoles":{"anyOf":[{"$ref":"#/components/schemas/VariableRolesSchema"},{"type":"null"}]},"derivedColumns":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/DtDerivedColumnInfoSchema"}},{"type":"null"}]},"dataSignature":{"type":"string"},"configSignature":{"type":"string"},"nTrainSamples":{"type":["number","null"]},"causalGraph":{"type":"array","items":{"$ref":"#/components/schemas/CausalRelationshipSchema"}},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/CausalNodeSchema"}},"evaluation":{"anyOf":[{"$ref":"#/components/schemas/EvaluationResultSchema"},{"type":"null"}]},"panelEvaluation":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/EvaluationResultSchema"}},{"type":"null"}]},"graphRecommendations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/GraphRecommendationsSchema"}},{"type":"null"}]},"environmentColumns":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"selectedEnvironmentColumns":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"selectedTimeColumnName":{"type":["string","null"]},"environmentSelection":{"anyOf":[{"$ref":"#/components/schemas/EnvironmentSelectionSchema"},{"type":"null"}]},"extraOps":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/OperationSchema"}},{"type":"null"}]},"nEnvironments":{"type":["number","null"]},"latentClusters":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/LatentClusterInfoSchema"}},{"type":"null"}]},"latentDiscoveryConfig":{"anyOf":[{"$ref":"#/components/schemas/LatentDiscoveryConfigSchema"},{"type":"null"}]},"nodeDomains":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"]}},{"type":"null"}]},"lastTimestampMs":{"type":["number","null"]},"headCommit":{"anyOf":[{"type":"integer"},{"type":"null"}]},"trainedWindowSignature":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]},"trainedWindowProfile":{"anyOf":[{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ColumnWindowProfileSchema"}},{"type":"null"}]},"resolvedInputs":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"datasetId":{"type":"string"},"versionId":{"type":["string","null"]},"deltaVersion":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"required":["datasetId"]}},{"type":"null"}]},"updateEligibility":{"anyOf":[{"type":"object","properties":{"updateMode":{"type":"string","enum":["assimilable","retrain_required","up_to_date","unsupported"]},"reasons":{"type":"array","items":{"type":"string"},"default":[]},"newRows":{"type":["number","null"]},"fromTsMs":{"type":["number","null"]},"toTsMs":{"type":["number","null"]},"historyDiff":{"anyOf":[{"$ref":"#/components/schemas/HistoryDiffSchema"},{"type":"null"}]}},"required":["updateMode"]},{"type":"null"}]},"trainingStages":{"anyOf":[{"type":"object","properties":{"confounderModelling":{"type":"boolean"},"equationDiscovery":{"type":"boolean"},"lagScreening":{"type":["boolean","null"]},"evalHorizons":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/EvalHorizonSchema"}},{"type":"null"}]}},"required":["confounderModelling","equationDiscovery"]},{"type":"null"}]},"timeComponent":{"anyOf":[{"$ref":"#/components/schemas/TimeComponentArtifactSchema"},{"type":"null"}]},"causalAlgorithmVersion":{"type":["string","null"]},"digitalTwinAlgorithmVersion":{"type":["string","null"]},"shardCount":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"maxLag":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}]},"layout":{"anyOf":[{"type":"object","properties":{"success":{"type":"boolean"},"positions":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},{"type":"null"}]},"edgeWaypoints":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},{"type":"null"}]}},"required":["success"]},{"type":"null"}]},"lifecycleState":{"$ref":"#/components/schemas/LifecycleStateEnum","default":"created"},"currentTaskId":{"type":["string","null"]},"failureContext":{"anyOf":[{"$ref":"#/components/schemas/FailureContextSchema"},{"type":"null"}]},"traces":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","properties":{"start":{"type":["string","null"]},"end":{"type":["string","null"]},"name":{"type":["string","null"]}}}},{"type":"null"}]},"arrayFeatureMap":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"arrayFeatureToBase":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]}},"required":["id","twinId","organisationId","workspaceId","versionMajor","versionMinor","versionPatch","sourceId","type","dataSignature","configSignature","causalGraph","nodes"]}]},"ChangeLogSchema":{"type":"object","properties":{"temporalDependenciesDiffs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TemporalDependencyChangeSchema"}},{"type":"null"}]},"fixedSubGraphDiffs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/FixedSubGraphChangeSchema"}},{"type":"null"}]},"causalGraphDiffs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/CausalGraphChangeSchema"}},{"type":"null"}]},"nodesDiffs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/NodeChangeSchema"}},{"type":"null"}]},"evaluationDiffs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/EvaluationChangeSchema"}},{"type":"null"}]}}},"TemporalDependencyChangeSchema":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ChangeTypeEnum"},"variable":{"type":"string"},"oldPrerequisites":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"newPrerequisites":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"required":["type","variable"]},"ChangeTypeEnum":{"type":"string","enum":["added","removed","modified"]},"FixedSubGraphChangeSchema":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ChangeTypeEnum"},"changeTarget":{"type":"string","enum":["relationships","antiRelationships"]},"relationship":{"$ref":"#/components/schemas/CausalRelationshipSchema"}},"required":["type","changeTarget","relationship"]},"CausalRelationshipSchema":{"type":"object","properties":{"source":{"type":"string"},"target":{"type":"string"},"strength":{"type":"number"},"strengthStatus":{"anyOf":[{"type":"string","enum":["measured","not_measured"]},{"type":"null"}]},"timeLagEffects":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"lag":{"type":"number"},"strength":{"type":"number"},"granularity":{"type":["string","null"]}},"required":["lag","strength"]}},{"type":"null"}]},"cyclicalEffects":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"frequency":{"type":"string"},"strength":{"type":"number"}},"required":["frequency","strength"]}},{"type":"null"}]},"confidence":{"type":["number","null"]},"agreementRate":{"type":["number","null"]},"isEnvironmentGated":{"type":"boolean","default":false}},"required":["source","target","strength"]},"CausalGraphChangeSchema":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ChangeTypeEnum"},"relationship":{"$ref":"#/components/schemas/CausalRelationshipSchema"},"oldRelationship":{"anyOf":[{"$ref":"#/components/schemas/CausalRelationshipSchema"},{"type":"null"}]}},"required":["type","relationship"]},"NodeChangeSchema":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ChangeTypeEnum"},"node":{"$ref":"#/components/schemas/CausalNodeSchema"},"oldNode":{"anyOf":[{"$ref":"#/components/schemas/CausalNodeSchema"},{"type":"null"}]}},"required":["type","node"]},"CausalNodeSchema":{"type":"object","properties":{"name":{"type":"string"},"nodeType":{"$ref":"#/components/schemas/NodeTypeEnum","default":"observed"},"type":{"$ref":"#/components/schemas/SchemaMainTypeEnum"},"categories":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"latentClusterId":{"type":["number","null"]},"environmentColumns":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"isDerived":{"type":"boolean","default":false},"symbolicEquation":{"anyOf":[{"$ref":"#/components/schemas/SymbolicEquationSchema"},{"type":"null"}]},"derivedInfo":{"anyOf":[{"$ref":"#/components/schemas/DtDerivedColumnInfoSchema"},{"type":"null"}]},"parentImpacts":{"anyOf":[{"$ref":"#/components/schemas/NodeParentImpactsSchema"},{"type":"null"}],"description":"Model-based driver contribution shares computed after training"}},"required":["name","type"]},"NodeTypeEnum":{"type":"string","enum":["observed","latent","latent_inter","latent_intra","environment"]},"SchemaMainTypeEnum":{"type":"string","enum":["None","String","Category","Number","Boolean","DateTime","Array","Unknown"]},"SymbolicEquationSchema":{"type":"object","properties":{"expression":{"type":"string"},"r2":{"type":"number"},"noisePercentage":{"type":"number"},"termBreakdown":{"type":"array","items":{"$ref":"#/components/schemas/SymbolicTermSchema"}},"complexity":{"type":"number"},"explanationType":{"type":"string","enum":["regression","classification_rules","conditional_probability"],"default":"regression"},"epsilonSigma":{"type":["number","null"]},"epsilonSigmaRelative":{"type":["number","null"]},"expressionWithNoise":{"type":["string","null"]},"discoveryMethod":{"type":["string","null"]},"parentContributions":{"type":"array","items":{"$ref":"#/components/schemas/SymbolicParentContributionSchema"}},"unexplainedPct":{"type":["number","null"]},"directionReferenceClass":{"type":["string","null"]},"alternatives":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SymbolicEquationAlternativeSchema"}},{"type":"null"}],"description":"Pareto-front alternatives to the chosen equation (balanced / fewer terms / better fit); absent until discovery emits them"}},"required":["expression","r2","noisePercentage","termBreakdown","complexity"]},"SymbolicTermSchema":{"type":"object","properties":{"expression":{"type":"string"},"parentVariable":{"type":["string","null"]},"parentVariables":{"type":"array","items":{"type":"string"}},"coefficient":{"type":"number"},"operator":{"type":"string"},"contributionPercentage":{"type":"number"}},"required":["expression","coefficient","operator","contributionPercentage"]},"SymbolicParentContributionSchema":{"type":"object","properties":{"parent":{"type":"string"},"contributionPct":{"type":"number"},"signedEffect":{"type":"number"},"direction":{"type":"string","enum":["positive","negative","mixed","none"]},"terms":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["included","noEffect"]}},"required":["parent","contributionPct","signedEffect","direction","terms","status"]},"SymbolicEquationAlternativeSchema":{"type":"object","properties":{"label":{"type":"string","description":"How this alternative trades off, e.g. 'Balanced', 'Fewer terms', 'Better fit'"},"expression":{"type":"string"},"r2":{"type":["number","null"]},"complexity":{"type":["number","null"]}},"required":["label","expression"]},"DtDerivedColumnInfoSchema":{"type":"object","properties":{"derivedType":{"type":"string"},"targetColumn":{"type":"string"},"sourceColumns":{"type":"array","items":{"type":"string"}},"expression":{"type":"string"},"r2":{"type":["number","null"]},"isDeterministic":{"type":"boolean"},"implausibilityReason":{"type":["string","null"]},"lag":{"type":["number","null"]},"cumulativeDirection":{"type":["string","null"]},"seasonalTerms":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SeasonalTermSchema"}},{"type":"null"}]},"isMonotonicallyIncreasing":{"type":["boolean","null"]},"isMonotonicallyDecreasing":{"type":["boolean","null"]}},"required":["derivedType","targetColumn","sourceColumns","expression","isDeterministic"]},"SeasonalTermSchema":{"type":"object","properties":{"period":{"type":"number"},"order":{"type":"number","default":1}},"required":["period"]},"NodeParentImpactsSchema":{"type":"object","properties":{"node":{"type":"string"},"method":{"type":"string","enum":["forecast_attribution","fwl_betas","gaamt_betas","cat_logit_betas","do_contrast"]},"parents":{"type":"array","items":{"$ref":"#/components/schemas/ParentImpactEntrySchema"}},"exogenous":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ParentImpactEntrySchema"}},{"type":"null"}],"description":"Trend/seasonal/level drivers on the same 0-100 scale as parents"},"nonParentShare":{"type":["number","null"]}},"required":["node","method","parents"]},"ParentImpactEntrySchema":{"type":"object","properties":{"parent":{"type":"string"},"impactPct":{"type":"number","description":"Share of total driver influence on the node, 0-100"},"signedEffect":{"type":"number"},"lagBreakdown":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}]}},"required":["parent","impactPct","signedEffect"]},"EvaluationChangeSchema":{"type":"object","properties":{"type":{"type":"string","enum":["improvement","worsening"]},"metric":{"type":"string"},"oldValue":{"type":["number","null"]},"newValue":{"type":"number"},"percentChange":{"type":["number","null"]}},"required":["type","metric","newValue"]},"DigitalTwinTypeEnum":{"type":"string","enum":["static","temporal","multi-environment-temporal","multi-environment-static"]},"SchemaEntryModelSchema":{"type":"object","properties":{"field":{"type":"string"},"type":{"$ref":"#/components/schemas/SchemaMainTypeEnum"},"subtype":{"anyOf":[{"$ref":"#/components/schemas/SchemaSubTypeEnum"},{"type":"null"}]},"availableTypes":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/SchemaMainTypeEnum"}},{"type":"null"}]},"isIndex":{"type":["boolean","null"]},"categories":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"aliases":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"description":{"type":["string","null"]},"displayWidth":{"type":["number","null"]},"originalFormat":{"type":["string","null"]},"displayFormat":{"type":["string","null"]},"unit":{"type":["string","null"]},"unitModifier":{"type":["number","null"]},"dateOrderAssumed":{"type":["boolean","null"]}},"required":["field","type"]},"SchemaSubTypeEnum":{"type":"string","enum":["Integer","Float","UnsignedInteger","UnsignedFloat","String","Number","Category","Boolean","DateTime"]},"TemporalDependenciesSchema":{"anyOf":[{"not":{}},{"anyOf":[{"$ref":"#/components/schemas/TemporalDependenciesObjectSchema"},{"type":"null"}]}]},"TemporalDependenciesObjectSchema":{"type":"object","properties":{"prerequisites":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["prerequisites"]},"TimeSeriesMetadataSchema":{"type":"object","properties":{"colName":{"type":"string","description":"Column name for the time series"},"granularity":{"type":"string","enum":["ms","s","min","h","D","W","ME","Y","L","S","T","H"],"description":"Current granularity of the time series"},"validGranularities":{"type":"array","items":{"type":"string"},"description":"List of valid granularities"},"startDate":{"type":"string","description":"Start date of the time series"},"endDate":{"type":"string","description":"End date of the time series"},"typicalDeltaSeconds":{"type":["number","null"]},"selectedGrid":{"type":["string","null"]},"candidateGrids":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"scoring":{"anyOf":[{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"number"}}},{"type":"null"}]},"coverage":{"anyOf":[{"$ref":"#/components/schemas/TimeSeriesCoverageSchema"},{"type":"null"}],"description":"Observed vs imputed grid steps; absent on twins trained before this existed"}},"required":["colName","granularity","validGranularities","startDate","endDate"]},"TimeSeriesCoverageSchema":{"type":"object","properties":{"observedSteps":{"type":"number","description":"Grid steps that carried at least one observed row"},"gridSteps":{"type":"number","description":"Steps on the dense grid the twin trains on"},"imputedSteps":{"type":"number","description":"Grid steps reconstructed by imputation, never measured"},"gapCount":{"type":"number","description":"Total gap runs; `gaps` lists only the largest"},"gaps":{"type":"array","items":{"$ref":"#/components/schemas/TimeSeriesGapSchema"}}},"required":["observedSteps","gridSteps","imputedSteps","gapCount","gaps"]},"TimeSeriesGapSchema":{"type":"object","properties":{"startDate":{"type":"string","description":"First grid step in the gap"},"endDate":{"type":"string","description":"Last grid step in the gap"},"missingSteps":{"type":"number","description":"Consecutive grid steps with no observed rows"}},"required":["startDate","endDate","missingSteps"]},"FixedSubGraphSchema":{"type":"object","properties":{"relationships":{"type":"array","items":{"$ref":"#/components/schemas/CausalRelationshipSchema"}},"antiRelationships":{"type":"array","items":{"$ref":"#/components/schemas/CausalRelationshipSchema"}}},"required":["relationships","antiRelationships"]},"VariableRolesSchema":{"type":"object","properties":{"sources":{"type":"array","items":{"type":"string"}},"targets":{"type":"array","items":{"type":"string"}}},"required":["sources","targets"]},"EvaluationResultSchema":{"type":"object","properties":{"modelType":{"type":"string","enum":["cbn","tcbn"],"description":"Type of the model"},"nodeMetrics":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/NodeMetricsSchema"},"description":"Metrics for each node"},"globalMetrics":{"type":"object","properties":{"logLikelihood":{"type":["number","null"],"description":"Overall log-likelihood"},"averageMse":{"type":["number","null"],"description":"Overall mean squared error"},"averageMae":{"type":["number","null"],"description":"Overall mean absolute error"},"averageAccuracy":{"type":["number","null"],"description":"Overall accuracy"},"averageMape":{"type":["number","null"],"description":"Overall mean absolute percentage error"}},"description":"Global metrics"},"skippedReason":{"anyOf":[{"type":"string","enum":["insufficient_data"]},{"type":"null"}],"description":"Set when evaluation was deliberately skipped"},"skipReasons":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"User-facing explanation of why evaluation was skipped"},"nEvalPoints":{"type":["number","null"],"description":"Number of holdout time steps evaluation used (or would have used)"}},"required":["modelType","nodeMetrics","globalMetrics"]},"NodeMetricsSchema":{"type":"object","properties":{"accuracy":{"type":["number","null"],"description":"Classification accuracy"},"accuracyPerClass":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}],"description":"Classification accuracy per class"},"weightedAccuracy":{"type":["number","null"],"description":"Weighted classification accuracy"},"falsePositiveRate":{"type":["number","null"],"description":"False positive rate"},"falseNegativeRate":{"type":["number","null"],"description":"False negative rate"},"truePositiveRate":{"type":["number","null"],"description":"True positive rate"},"trueNegativeRate":{"type":["number","null"],"description":"True negative rate"},"precision":{"type":["number","null"],"description":"Precision, macro-averaged across classes"},"recall":{"type":["number","null"],"description":"Recall, macro-averaged across classes"},"f1Score":{"type":["number","null"],"description":"F1 score, macro-averaged across classes"},"precisionPerClass":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}],"description":"Precision per class"},"recallPerClass":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}],"description":"Recall per class"},"f1ScorePerClass":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}],"description":"F1 score per class"},"positiveClassLabel":{"type":["string","null"],"description":"Decoded label of encoded class 1, the anchor for TPR/FPR/TNR/FNR"},"mse":{"type":["number","null"],"description":"Mean squared error"},"r2":{"type":["number","null"],"description":"R-squared"},"logLikelihood":{"type":["number","null"],"description":"Log-likelihood"},"auc":{"type":["number","null"],"description":"Area under ROC curve"},"brierScore":{"type":["number","null"],"description":"Brier score"},"mae":{"type":["number","null"],"description":"Mean absolute error"},"mape":{"anyOf":[{"type":"object","additionalProperties":{"type":["number","null"]}},{"type":"null"}],"description":"Mean absolute percentage error per horizon"}}},"GraphRecommendationsSchema":{"type":"object","properties":{"x":{"type":"string"},"y":{"type":"string"},"direction":{"type":"string","enum":["forward","backward"]},"reasons":{"type":"array","items":{"type":"string"}}},"required":["x","y","direction","reasons"]},"EnvironmentSelectionSchema":{"type":"object","properties":{"baseline":{"type":"string","enum":["all","none"]},"exceptions":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}}},"required":["baseline","exceptions"]},"OperationSchema":{"type":"object","properties":{"id":{"type":"string"},"sourceId":{"type":"string"},"config":{"$ref":"#/components/schemas/OperationConfigSchema"}},"required":["id","sourceId","config"]},"OperationConfigSchema":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"FILTER"},"filterGroup":{"anyOf":[{"$ref":"#/components/schemas/FilterSchema"},{"$ref":"#/components/schemas/FilterGroupSchema"}]}},"required":["type","filterGroup"]},{"type":"object","properties":{"type":{"type":"string","const":"AGGREGATE"},"groupByColumns":{"type":"array","items":{"type":"string"}},"aggregations":{"type":"array","items":{"$ref":"#/components/schemas/AggregationFunctionSchema"}}},"required":["type","groupByColumns","aggregations"]},{"type":"object","properties":{"type":{"type":"string","const":"JOIN"},"joinType":{"$ref":"#/components/schemas/JoinTypeEnum"},"columnPairs":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/JoinColumnPairSchema"}},{"type":"null"}]},"leftField":{"type":["string","null"]},"rightField":{"type":["string","null"]},"conflictResolution":{"$ref":"#/components/schemas/JoinConflictResolutionEnum"},"leftPrefix":{"type":["string","null"]},"rightPrefix":{"type":["string","null"]}},"required":["type","joinType","conflictResolution"]},{"type":"object","properties":{"type":{"type":"string","const":"CONCATENATE"},"topSource":{"type":["string","null"]},"bottomSource":{"type":["string","null"]},"sources":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"columnMapping":{"type":"object","additionalProperties":{"type":"string"}},"unmatchedRule":{"$ref":"#/components/schemas/UnmatchedRuleEnum"},"discriminatorColumn":{"type":["string","null"]},"discriminatorValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]}},"required":["type","columnMapping","unmatchedRule"]},{"type":"object","properties":{"type":{"type":"string","const":"SORT"},"sortColumns":{"type":"array","items":{"$ref":"#/components/schemas/SortColumnSchema"}}},"required":["type","sortColumns"]},{"type":"object","properties":{"type":{"type":"string","const":"SQL_QUERY"},"query":{"type":"string"},"columnSourceAliases":{"anyOf":[{"type":"object","additionalProperties":{"type":"string"}},{"type":"null"}]}},"required":["type","query"]},{"type":"object","properties":{"type":{"type":"string","const":"SPLIT_COLUMN"},"columnToSplit":{"type":"string"},"splitType":{"$ref":"#/components/schemas/SplitTypeEnum"},"delimiter":{"type":["string","null"]},"columns":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/NewColumnDefinitionSchema"}},{"type":"null"}]}},"required":["type","columnToSplit","splitType"]},{"type":"object","properties":{"type":{"type":"string","const":"DROP_COLUMNS"},"columns":{"type":"array","items":{"type":"string"}}},"required":["type","columns"]},{"type":"object","properties":{"type":{"type":"string","const":"REMOVE_DUPLICATES"},"column":{"type":["string","null"]},"keep":{"$ref":"#/components/schemas/KeepEnum","default":"first"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"IMPUTE_NULLS"},"method":{"$ref":"#/components/schemas/ImputeMethodEnum","default":"constant"},"column":{"type":["string","null"]},"fillValue":{"anyOf":[{"type":["string","number","boolean"]},{"type":"null"}]},"imputations":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"column":{"type":"string"},"method":{"$ref":"#/components/schemas/ImputeMethodEnum","default":"constant"},"fillValue":{"anyOf":[{"type":["string","number","boolean"]},{"type":"null"}]}},"required":["column"]}},{"type":"null"}]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"DROP_NULLS"},"axis":{"type":"string","enum":["rows","empty_columns"],"default":"rows"},"column":{"type":["string","null"]},"columns":{"type":"array","items":{"type":"string"},"default":[]},"nullThresholdPercent":{"type":"number","default":100}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"REPLACE_VALUES"},"column":{"type":"string"},"mapping":{"type":"object","additionalProperties":{"type":["string","null"]}}},"required":["type","column","mapping"]},{"type":"object","properties":{"type":{"type":"string","const":"REPLACE_TYPE"},"changes":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"column":{"type":"string"},"toType":{"$ref":"#/components/schemas/SchemaMainTypeEnum"},"toSubType":{"anyOf":[{"$ref":"#/components/schemas/SchemaSubTypeEnum"},{"type":"null"}]},"dateFormat":{"type":["string","null"]}},"required":["column","toType"]}},{"type":"null"}]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"INTERPOLATE_TIME"},"column":{"type":"string"},"frequency":{"type":"string"},"method":{"$ref":"#/components/schemas/InterpolateTimeMethodEnum"}},"required":["type","column","frequency","method"]},{"type":"object","properties":{"type":{"type":"string","const":"CLIP_OUTLIERS"},"column":{"type":"string"},"lowerQuantile":{"type":"number","default":0.05},"upperQuantile":{"type":"number","default":0.95}},"required":["type","column"]},{"type":"object","properties":{"type":{"type":"string","const":"NORMALIZE_NUMERIC"},"column":{"type":"string"},"method":{"$ref":"#/components/schemas/NormalizeNumericMethodEnum","default":"z_score"}},"required":["type","column"]},{"type":"object","properties":{"type":{"type":"string","const":"MAP_CATEGORIES"},"column":{"type":"string"},"mapping":{"type":"object","additionalProperties":{"type":"string"}},"defaultValue":{"type":["string","null"]}},"required":["type","column","mapping"]},{"type":"object","properties":{"type":{"type":"string","const":"TIME_SERIES_AGGREGATE"},"timeColumn":{"type":"string"},"granularity":{"type":"string","enum":["nanosecond","microsecond","millisecond","second","minute","hour","day","week","month","quarter","year"]},"aggregations":{"type":"array","items":{"$ref":"#/components/schemas/AggregationFunctionSchema"}},"dateFormat":{"anyOf":[{"$ref":"#/components/schemas/DatetimeFormatSchema"},{"type":"null"}]}},"required":["type","timeColumn","granularity","aggregations"]},{"type":"object","properties":{"type":{"type":"string","const":"TIME_SERIES_JOIN"},"joinType":{"$ref":"#/components/schemas/JoinTypeEnum"},"leftTimeColumn":{"type":"string"},"rightTimeColumn":{"type":"string"},"rightSource":{"type":"string"},"strategy":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"exact"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"granularity"},"granularity":{"type":"string","enum":["nanosecond","microsecond","millisecond","second","minute","hour","day","week","month","quarter","year"]}},"required":["type","granularity"]},{"type":"object","properties":{"type":{"type":"string","const":"asOf"},"direction":{"$ref":"#/components/schemas/AsOfDirectionEnum"},"tolerance":{"anyOf":[{"type":"object","properties":{"value":{"type":"number"},"unit":{"$ref":"#/components/schemas/ToleranceUnitEnum"}},"required":["value","unit"]},{"type":"null"}]}},"required":["type","direction"]},{"type":"object","properties":{"type":{"type":"string","const":"interval"},"leftEndColumn":{"type":"string"}},"required":["type","leftEndColumn"]}],"discriminator":{"propertyName":"type"}},"exactMatchKeys":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"leftField":{"type":"string"},"rightField":{"type":"string"}},"required":["leftField","rightField"]}},{"type":"null"}]},"multiMatch":{"$ref":"#/components/schemas/MultiMatchStrategyEnum"},"multiMatchAggregations":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/AggregationFunctionSchema"}},{"type":"null"}]}},"required":["type","joinType","leftTimeColumn","rightTimeColumn","rightSource","strategy","multiMatch"]},{"type":"object","properties":{"type":{"type":"string","const":"TRANSPOSE"},"timeColumn":{"type":"string"},"envColumns":{"type":"array","items":{"type":"string"}},"valueColumns":{"type":"array","items":{"type":"string"}},"columnTemplate":{"type":"string"},"joinStrategy":{"anyOf":[{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"exact"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","const":"granularity"},"granularity":{"type":"string","enum":["nanosecond","microsecond","millisecond","second","minute","hour","day","week","month","quarter","year"]}},"required":["type","granularity"]},{"type":"object","properties":{"type":{"type":"string","const":"asOf"},"direction":{"$ref":"#/components/schemas/AsOfDirectionEnum"},"tolerance":{"anyOf":[{"type":"object","properties":{"value":{"type":"number"},"unit":{"$ref":"#/components/schemas/ToleranceUnitEnum"}},"required":["value","unit"]},{"type":"null"}]}},"required":["type","direction"]}],"discriminator":{"propertyName":"type"}},{"type":"null"}]}},"required":["type","timeColumn","envColumns","valueColumns","columnTemplate"]},{"type":"object","properties":{"type":{"type":"string","const":"FREQUENCY_ANALYSIS"},"timeColumn":{"type":"string"},"valueColumns":{"type":"array","items":{"type":"string"}},"method":{"$ref":"#/components/schemas/FrequencyMethodEnum"},"windowFunction":{"$ref":"#/components/schemas/FrequencyWindowFunctionEnum","default":"hann"},"windowSize":{"type":["number","null"]},"overlap":{"type":"number","default":0.5},"samplingRateHz":{"type":["number","null"]},"outputFormat":{"$ref":"#/components/schemas/FrequencyOutputFormatEnum"},"frequencyRange":{"anyOf":[{"type":"object","properties":{"minHz":{"type":["number","null"]},"maxHz":{"type":["number","null"]}}},{"type":"null"}]},"frequencyUnit":{"$ref":"#/components/schemas/FrequencyUnitEnum","default":"hz"}},"required":["type","timeColumn","valueColumns","method","outputFormat"]},{"type":"object","properties":{"type":{"type":"string","const":"CYCLIC_AGGREGATE"},"timeColumn":{"type":"string"},"cycleComponent":{"$ref":"#/components/schemas/CyclicComponentEnum"},"aggregations":{"type":"array","items":{"$ref":"#/components/schemas/AggregationFunctionSchema"}}},"required":["type","timeColumn","cycleComponent","aggregations"]},{"type":"object","properties":{"type":{"type":"string","const":"DIFF"},"timeColumn":{"type":"string"},"columns":{"type":"array","items":{"type":"string"}},"partitionColumns":{"type":"array","items":{"type":"string"},"default":[]},"outputSuffix":{"type":"string","default":"_diff"},"replaceColumns":{"type":"boolean","default":false}},"required":["type","timeColumn","columns"]},{"type":"object","properties":{"type":{"type":"string","const":"DATE_DIFF"},"startColumn":{"type":"string"},"endColumn":{"type":"string"},"unit":{"$ref":"#/components/schemas/DateDiffUnitEnum","default":"days"},"sign":{"$ref":"#/components/schemas/DateDiffSignEnum","default":"signed"},"outputColumn":{"type":["string","null"]}},"required":["type","startColumn","endColumn"]},{"type":"object","properties":{"type":{"type":"string","const":"CUMULATIVE"},"timeColumn":{"type":"string"},"columns":{"type":"array","items":{"type":"string"}},"partitionColumns":{"type":"array","items":{"type":"string"},"default":[]},"outputSuffix":{"type":"string","default":"_cumsum"},"replaceColumns":{"type":"boolean","default":false}},"required":["type","timeColumn","columns"]},{"type":"object","properties":{"type":{"type":"string","const":"ARRAY_DECOMPOSE"},"column":{"type":"string"},"mode":{"$ref":"#/components/schemas/ArrayDecomposeModeEnum","default":"position"},"maxColumns":{"type":"integer","exclusiveMinimum":0,"default":500},"outputPrefix":{"type":"string","default":"_"}},"required":["type","column"]},{"type":"object","properties":{"type":{"type":"string","const":"ARRAY_CONSOLIDATE"},"groups":{"type":"array","items":{"type":"object","properties":{"columns":{"type":"array","items":{"type":"string"},"minItems":1},"outputColumn":{"type":"string"},"dropSource":{"type":"boolean","default":true},"includeNulls":{"type":"boolean","default":false}},"required":["columns","outputColumn"]},"minItems":1}},"required":["type","groups"]},{"type":"object","properties":{"type":{"type":"string","const":"ARRAY_EXPLODE"},"column":{"type":"string"},"outputColumn":{"type":["string","null"]},"preserveIndex":{"type":"boolean","default":false}},"required":["type","column"]},{"type":"object","properties":{"type":{"type":"string","const":"ARRAY_AGGREGATE"},"column":{"type":"string"},"aggregation":{"$ref":"#/components/schemas/ArrayAggregationKindEnum"},"outputColumn":{"type":["string","null"]}},"required":["type","column","aggregation"]},{"type":"object","properties":{"type":{"type":"string","const":"JSON_FLATTEN"},"column":{"type":"string"},"maxColumns":{"type":"integer","exclusiveMinimum":0,"default":500},"separator":{"type":"string","default":"."},"dropSource":{"type":"boolean","default":true}},"required":["type","column"]}],"discriminator":{"propertyName":"type"}},"FilterSchema":{"type":"object","properties":{"column":{"type":"string"},"comparisonOperator":{"$ref":"#/components/schemas/ComparisonOperatorEnum"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":["string","number","boolean"]}}]},"correctType":{"type":"boolean"}},"required":["column","comparisonOperator","value","correctType"]},"ComparisonOperatorEnum":{"type":"string","enum":["Equal to","Not Equal to","Contains","Does not contain","Starts with","Ends with","Is Empty","Is not Empty","Less than","Greater than","Less than or equal to","Greater than or equal to","Before","After","Array contains","Array contains any","Array contains all","Array does not contain","Array does not contain any","Array does not contain all","Array size equal to","Array size greater than","Array size less than"]},"FilterGroupSchema":{"type":"object","properties":{"booleanOperator":{"$ref":"#/components/schemas/LogicalOperatorEnum"},"filters":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/FilterSchema"},{"$ref":"#/components/schemas/FilterGroupSchema"}]}}},"required":["booleanOperator","filters"]},"LogicalOperatorEnum":{"type":"string","enum":["AND","OR"]},"AggregationFunctionSchema":{"type":"object","properties":{"column":{"type":"string"},"function":{"$ref":"#/components/schemas/AggregateFunctionEnum"},"alias":{"type":["string","null"]},"filter":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/FilterSchema"},{"$ref":"#/components/schemas/FilterGroupSchema"}]},{"type":"null"}]}},"required":["column","function"]},"AggregateFunctionEnum":{"type":"string","enum":["sum","avg","min","max","count","countDistinct","first","last","categoryShare"]},"JoinTypeEnum":{"type":"string","enum":["inner","left","right","full"]},"JoinColumnPairSchema":{"type":"object","properties":{"leftField":{"type":"string"},"rightField":{"type":"string"}},"required":["leftField","rightField"]},"JoinConflictResolutionEnum":{"type":"string","enum":["keep_left","keep_right","prefix"]},"UnmatchedRuleEnum":{"type":"string","enum":["error","drop","append"]},"SortColumnSchema":{"type":"object","properties":{"column":{"type":"string"},"direction":{"$ref":"#/components/schemas/SortDirectionEnum"}},"required":["column","direction"]},"SortDirectionEnum":{"type":"string","enum":["asc","desc"]},"SplitTypeEnum":{"type":"string","enum":["delimiter","pattern"]},"NewColumnDefinitionSchema":{"type":"object","properties":{"name":{"type":"string"},"pattern":{"type":["string","null"]}},"required":["name"]},"KeepEnum":{"type":"string","enum":["first","last"]},"ImputeMethodEnum":{"type":"string","enum":["mean","median","mode","constant"]},"InterpolateTimeMethodEnum":{"type":"string","enum":["linear","time","index"]},"NormalizeNumericMethodEnum":{"type":"string","enum":["min_max","z_score"]},"DatetimeFormatSchema":{"type":"string","minLength":1},"AsOfDirectionEnum":{"type":"string","enum":["backward","forward","nearest"]},"ToleranceUnitEnum":{"type":"string","enum":["us","ms","s","m","h","d"]},"MultiMatchStrategyEnum":{"type":"string","enum":["first","last","aggregate"]},"FrequencyMethodEnum":{"type":"string","enum":["fft","welch"]},"FrequencyWindowFunctionEnum":{"type":"string","enum":["hann","hamming","blackman","rectangular"]},"FrequencyOutputFormatEnum":{"type":"string","enum":["spectrogram","time_frequency_long"]},"FrequencyUnitEnum":{"type":"string","enum":["hz","per_minute","per_hour","per_day","per_week","per_month","per_year"]},"CyclicComponentEnum":{"type":"string","enum":["second_in_minute","minute_in_hour","hour_of_day","day_of_week","day_of_month","week_of_year","month_of_year","quarter_of_year"]},"DateDiffUnitEnum":{"type":"string","enum":["seconds","minutes","hours","days","weeks"]},"DateDiffSignEnum":{"type":"string","enum":["signed","absolute"]},"ArrayDecomposeModeEnum":{"type":"string","enum":["position","one_hot"]},"ArrayAggregationKindEnum":{"type":"string","enum":["mean","sum","min","max","median","count"]},"LatentClusterInfoSchema":{"type":"object","properties":{"clusterId":{"type":"number"},"affectedNodes":{"type":"array","items":{"type":"string"}},"estimatedDim":{"type":"number","default":1},"dicSatisfied":{"type":"boolean","default":true},"interColumnNames":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"intraColumnNames":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"modelStatus":{"anyOf":[{"$ref":"#/components/schemas/LatentModelStatusEnum"},{"type":"null"}]},"modelFailureReason":{"anyOf":[{"$ref":"#/components/schemas/LatentFitFailureReasonEnum"},{"type":"null"}]},"modelFailureDetail":{"type":["string","null"]},"avgLcScore":{"type":["number","null"]},"reconstructionError":{"type":["number","null"]},"envPredictability":{"type":["number","null"]},"memberLatentShare":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}]},"seasonalStrength":{"type":["number","null"]}},"required":["clusterId","affectedNodes"]},"LatentModelStatusEnum":{"type":"string","enum":["modelled","detectedOnly"]},"LatentFitFailureReasonEnum":{"type":"string","enum":["tooFewMembers","noNumericMembers","noExternalParents","allParentColumnsEmpty","insufficientCleanRows","fitError"]},"LatentDiscoveryConfigSchema":{"type":"object","properties":{"enabled":{"type":"boolean","default":true},"residualCorrelationThreshold":{"type":"number","default":0.3},"ciTestAlpha":{"type":"number","default":0.05},"minClusterSize":{"type":"number","default":2},"maxLatentDim":{"type":"number","default":5}}},"ColumnWindowProfileSchema":{"type":"object","properties":{"count":{"type":["number","null"]},"distinct":{"type":["number","null"]},"min":{"type":["string","null"]},"max":{"type":["string","null"]}}},"HistoryDiffSchema":{"type":"object","properties":{"changedColumns":{"type":"array","items":{"type":"object","properties":{"column":{"type":"string"},"stored":{"anyOf":[{"$ref":"#/components/schemas/ColumnWindowProfileSchema"},{"type":"null"}]},"current":{"anyOf":[{"$ref":"#/components/schemas/ColumnWindowProfileSchema"},{"type":"null"}]}},"required":["column"]},"default":[]},"deltaOperations":{"type":"array","items":{"type":"object","properties":{"datasetId":{"type":"string"},"version":{"type":"integer"},"operation":{"type":"string"},"timestampMs":{"type":["number","null"]}},"required":["datasetId","version","operation"]},"default":[]},"rewrittenDatasets":{"type":"array","items":{"type":"string"},"default":[]}}},"EvalHorizonSchema":{"type":"object","properties":{"count":{"type":"integer","exclusiveMinimum":0},"unit":{"$ref":"#/components/schemas/HorizonUnitEnum"}},"required":["count","unit"]},"HorizonUnitEnum":{"type":"string","enum":["S","T","H","D","W","ME","Y"]},"TimeComponentArtifactSchema":{"type":"object","properties":{"models":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimeDecompositionModelSchema"}},"varExplained":{"type":"object","additionalProperties":{"type":"number"}},"trainNSamples":{"type":"number"}},"required":["models","varExplained","trainNSamples"]},"TimeDecompositionModelSchema":{"type":"object","properties":{"theilSenSlope":{"type":"number"},"theilSenIntercept":{"type":"number"},"harmonic":{"anyOf":[{"$ref":"#/components/schemas/HarmonicFitSchema"},{"type":"null"}]}},"required":["theilSenSlope","theilSenIntercept"]},"HarmonicFitSchema":{"type":"object","properties":{"periodsWithHarmonics":{"type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}]}},"sinCosCoefficients":{"type":"array","items":{"type":"number"}},"productPairs":{"type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":[{"type":"number"},{"type":"number"}]}},"productCoefficients":{"type":"array","items":{"type":"number"}}},"required":["periodsWithHarmonics","sinCosCoefficients","productPairs","productCoefficients"]},"LifecycleStateEnum":{"type":"string","enum":["created","discovering","resolved","training","trained","failed","cancelled"]},"FailureContextSchema":{"type":"object","properties":{"error":{"type":"string"},"failedAtStage":{"type":"string","enum":["causal_discovery","model_training"]},"retryable":{"type":"boolean","default":true},"userFacing":{"type":"boolean","default":false}},"required":["error","failedAtStage"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions","summary":"Create version","description":"Derives a new version from an existing one — the retrain primitive. Body (all optional): bump (major | minor | patch, default patch), baseVersionId (default: the latest version), datasetId (point the new version at different data). The new version inherits the base's configuration and causal graph, resets all training outputs, and lands in lifecycleState resolved — train it with POST .../versions/{vId}/train. Version numbers never collide: the bumped component skips past any label already taken.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVersionInput"}}}},"responses":{"201":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DigitalTwinVersionEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Delete an environment group

> Removes the group from the twin. Nothing downstream is deleted: simulation runs scoped to the group keep the membership frozen on their environmentGroupSnapshots, and any saved link to the group id simply stops resolving. 404 when the twin has no group with this id.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/environment-groups/{groupId}":{"delete":{"operationId":"delete-api-v1-workspaces-{wsId}-digital-twins-{id}-environment-groups-{groupId}","summary":"Delete an environment group","description":"Removes the group from the twin. Nothing downstream is deleted: simulation runs scoped to the group keep the membership frozen on their environmentGroupSnapshots, and any saved link to the group id simply stops resolving. 404 when the twin has no group with this id.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"groupId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: groupId"}],"responses":{"204":{"description":"No Content"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Update an environment group

> Renames an environment group and/or replaces its membership rule. Send at least one of \`name\` or \`definition\`; a definition replaces the stored one wholesale rather than merging into it. Names stay unique per twin, so a colliding rename is 409 Conflict. Groups are twin-level, so the change applies to every version at once — a saved group is re-resolved against whichever version reads it next, and runs already submitted keep the membership frozen on their snapshots.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UpdateEnvironmentGroupInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"New display name; unique per twin"},"definition":{"$ref":"#/components/schemas/EnvironmentGroupDefinitionSchema","description":"Replacement membership rule"}}},"EnvironmentGroupDefinitionSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["columnValues","environments","statFilters"]},"columnValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},{"type":"null"}]},"statFilters":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"},{"type":"null"}]},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}]}},"required":["mode"]},"EnvStatFilterGroupSchema":{"type":"object","properties":{"booleanOperator":{"type":"string","enum":["AND","OR"]},"filters":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterSchema"},{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"}]}}},"required":["booleanOperator","filters"]},"EnvStatFilterSchema":{"type":"object","properties":{"column":{"type":"string"},"comparisonOperator":{"type":"string"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":["string","number","boolean"]}}]},"reduce":{"anyOf":[{"$ref":"#/components/schemas/EnvStatReduceEnum"},{"type":"null"}]}},"required":["column","comparisonOperator","value"]},"EnvStatReduceEnum":{"type":"string","enum":["value","mean","min","max","any"]},"EnvironmentGroupEnvelope":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EnvironmentGroupSchema"}},"required":["data"]},"EnvironmentGroupSchema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"definition":{"$ref":"#/components/schemas/EnvironmentGroupDefinitionSchema"},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"]},"updatedAt":{"type":["string","null"]},"splitColumn":{"type":["string","null"]},"splitValue":{"type":["string","null"]}},"required":["id","name","definition","createdAt"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/environment-groups/{groupId}":{"patch":{"operationId":"patch-api-v1-workspaces-{wsId}-digital-twins-{id}-environment-groups-{groupId}","summary":"Update an environment group","description":"Renames an environment group and/or replaces its membership rule. Send at least one of `name` or `definition`; a definition replaces the stored one wholesale rather than merging into it. Names stay unique per twin, so a colliding rename is 409 Conflict. Groups are twin-level, so the change applies to every version at once — a saved group is re-resolved against whichever version reads it next, and runs already submitted keep the membership frozen on their snapshots.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"groupId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: groupId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEnvironmentGroupInput"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentGroupEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get version

> Returns one version by id from platform MongoDB. Version must belong to this twin and workspace. Includes causalGraph, nodes, inputFields, lifecycleState, variableRoles, temporalDependencies, evaluation, and the data it models as datasetId or sourceId (matching how the twin was created).

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}","summary":"Get version","description":"Returns one version by id from platform MongoDB. Version must belong to this twin and workspace. Includes causalGraph, nodes, inputFields, lifecycleState, variableRoles, temporalDependencies, evaluation, and the data it models as datasetId or sourceId (matching how the twin was created).","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Delete version

> Deletes the version. Proxies DELETE to data-service so orchestrator/model state is removed; platform version record is not deleted by this route. Requires digital-twins:delete and full permission.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}":{"delete":{"operationId":"delete-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}","summary":"Delete version","description":"Deletes the version. Proxies DELETE to data-service so orchestrator/model state is removed; platform version record is not deleted by this route. Requires digital-twins:delete and full permission.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"responses":{"204":{"description":"No Content"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Download completed export

> Streams the completed export zip (application/zip). 404 if the run does not exist in this workspace; 409 while the export job is still running. Requires exports:read scope.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/export/{pipelineRunId}/download":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-export-{pipelineRunId}-download","summary":"Download completed export","description":"Streams the completed export zip (application/zip). 404 if the run does not exist in this workspace; 409 while the export job is still running. Requires exports:read scope.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"pipelineRunId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: pipelineRunId"}],"responses":{"200":{"description":"Successful response","content":{"application/octet-stream":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Run causal discovery

> Runs causal discovery for this version (infers causal graph from data). Proxies to data-service execute-causal-discovery. Returns 202 with jobId (pipelineRunId or workflowId) and links (self, cancel). Poll jobs/{jobId} for status; when complete, the version's causal graph is updated. Optional body: webhookUrl — POSTed once (best effort, unsigned) when the job reaches a terminal state; polling stays the source of truth.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"WebhookBody":{"type":"object","properties":{"webhookUrl":{"type":["string","null"],"format":"uri"}}},"AsyncJobAccepted":{"type":"object","properties":{"data":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","description":"pending until the job reaches a terminal status"},"createdAt":{"type":"string"},"links":{"type":"object","properties":{"self":{"type":"string","description":"Poll this until the status is terminal"},"cancel":{"type":"string"}},"required":["self"]}},"required":["jobId","status","links"],"description":"Envelope for asynchronous pipeline work. Poll links.self until the job reaches a terminal status."}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/discover":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-discover","summary":"Run causal discovery","description":"Runs causal discovery for this version (infers causal graph from data). Proxies to data-service execute-causal-discovery. Returns 202 with jobId (pipelineRunId or workflowId) and links (self, cancel). Poll jobs/{jobId} for status; when complete, the version's causal graph is updated. Optional body: webhookUrl — POSTed once (best effort, unsigned) when the job reaches a terminal state; polling stays the source of truth.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookBody"}}}},"responses":{"202":{"description":"Accepted; poll the linked resource for completion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncJobAccepted"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## List the version's environments

> Multi-environment (panel) twins: returns environmentColumns and the environments the version's data contains — each with its envKey, column values, and sample size. Works before training (computed from the data, cached server-side). Use the envKeys to target specific environments in sample, intervene, and forecast calls.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/environments":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-environments","summary":"List the version's environments","description":"Multi-environment (panel) twins: returns environmentColumns and the environments the version's data contains — each with its envKey, column values, and sample size. Works before training (computed from the data, cached server-side). Use the envKeys to target specific environments in sample, intervene, and forecast calls.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get model evaluation

> Returns evaluation and panelEvaluation for this version from platform MongoDB. No proxy; values are set when training or run-pipeline completes. Null if not yet evaluated.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/evaluation":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-evaluation","summary":"Get model evaluation","description":"Returns evaluation and panelEvaluation for this version from platform MongoDB. No proxy; values are set when training or run-pipeline completes. Null if not yet evaluated.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get causal graph

> Returns the version's causal graph: relationships (edges), nodes, and fixedSubGraph (user-fixed edges/anti-edges). Read from platform MongoDB.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/graph":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-graph","summary":"Get causal graph","description":"Returns the version's causal graph: relationships (edges), nodes, and fixedSubGraph (user-fixed edges/anti-edges). Read from platform MongoDB.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Replace causal graph

> Replaces the entire causal graph. Body: relationships (array of {source, target, strength?}), nodes (array of {name, nodeType, type}). Overwrites causalGraph and nodes in platform MongoDB. fixedSubGraph is left unchanged — pin or forbid edges through graph/fixed.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"PutGraphInput":{"type":"object","properties":{"relationships":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"target":{"type":"string"},"strength":{"type":"number"}},"required":["source","target"]}},"nodes":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"nodeType":{"type":"string"},"type":{"type":"string"}},"required":["name","nodeType","type"]}}},"required":["relationships","nodes"]},"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/graph":{"put":{"operationId":"put-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-graph","summary":"Replace causal graph","description":"Replaces the entire causal graph. Body: relationships (array of {source, target, strength?}), nodes (array of {name, nodeType, type}). Overwrites causalGraph and nodes in platform MongoDB. fixedSubGraph is left unchanged — pin or forbid edges through graph/fixed.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PutGraphInput"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get version parameters

> Returns learned or configured parameters for this version (e.g. model params). Proxies to data-service GET /api/digital-twin/{twinId}/version/{vId}/params. Only available after training or pipeline run.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/params":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-params","summary":"Get version parameters","description":"Returns learned or configured parameters for this version (e.g. model params). Proxies to data-service GET /api/digital-twin/{twinId}/version/{vId}/params. Only available after training or pipeline run.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Run full pipeline

> Runs the full digital-twin pipeline: discovery (if needed), temporal dependencies, variable roles, training. Version must have a dataset (datasetId). Platform fetches the dataset schema and may auto-populate inputFields on the version if empty. Proxies to data-service execute-full-pipeline. Returns 202 with jobId and links (self, cancel). Poll jobs/{jobId} for completion. Optional body: webhookUrl — POSTed once (best effort, unsigned) at the terminal state.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"WebhookBody":{"type":"object","properties":{"webhookUrl":{"type":["string","null"],"format":"uri"}}},"AsyncJobAccepted":{"type":"object","properties":{"data":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","description":"pending until the job reaches a terminal status"},"createdAt":{"type":"string"},"links":{"type":"object","properties":{"self":{"type":"string","description":"Poll this until the status is terminal"},"cancel":{"type":"string"}},"required":["self"]}},"required":["jobId","status","links"],"description":"Envelope for asynchronous pipeline work. Poll links.self until the job reaches a terminal status."}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/run-pipeline":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-run-pipeline","summary":"Run full pipeline","description":"Runs the full digital-twin pipeline: discovery (if needed), temporal dependencies, variable roles, training. Version must have a dataset (datasetId). Platform fetches the dataset schema and may auto-populate inputFields on the version if empty. Proxies to data-service execute-full-pipeline. Returns 202 with jobId and links (self, cancel). Poll jobs/{jobId} for completion. Optional body: webhookUrl — POSTed once (best effort, unsigned) at the terminal state.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookBody"}}}},"responses":{"202":{"description":"Accepted; poll the linked resource for completion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncJobAccepted"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Sample raw draws from the trained model

> Runs conditional sampling in-process on the trained model and returns the raw joint posterior draws, columnar — the primitive every simulation family is built on. Body: spec (InterventionSpec | TimeSeriesInterventionSpec | PanelInterventionSpec with interventions, valueSpecs, and optional conditions), n (default 1000, max 100000), seed (panel twins derive stable per-environment child seeds from it). Non-panel twins answer {columns: {column: values}, n}; panel twins answer {environments: {envKey: {column: values}}, n}, each environment sampled independently. Version must be trained. Synchronous — no job to poll.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"SampleTwinInput":{"type":"object","properties":{"spec":{"type":"object","additionalProperties":{},"description":"Sampling spec, discriminated by type: intervention (static/temporal twins), time_series_intervention, or panel_intervention (multi-environment twins, optional environments list). Carries interventions with valueSpec (setValue, relativeChange, setProbability, …) and optional per-intervention conditions. Deep validation happens server-side."},"n":{"type":"integer","minimum":1,"maximum":100000,"description":"Number of joint posterior draws (default 1000)"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Reproducibility seed. Panel twins derive a stable per-environment child seed from it."}},"required":["spec"]},"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/sample":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-sample","summary":"Sample raw draws from the trained model","description":"Runs conditional sampling in-process on the trained model and returns the raw joint posterior draws, columnar — the primitive every simulation family is built on. Body: spec (InterventionSpec | TimeSeriesInterventionSpec | PanelInterventionSpec with interventions, valueSpecs, and optional conditions), n (default 1000, max 100000), seed (panel twins derive stable per-environment child seeds from it). Non-panel twins answer {columns: {column: values}, n}; panel twins answer {environments: {envKey: {column: values}}, n}, each environment sampled independently. Version must be trained. Synchronous — no job to poll.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SampleTwinInput"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Generate scenario from natural-language query

> Generates a structured simulation scenario from a natural-language query using the platform LLM (same generator as the New Simulation wizard's Generate from Query). Body: query, optional scenarioType. Proxies to data-service scenario-from-query. Returns the generated scenario plus a validation report; run it via POST simulations.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"ScenarioFromQueryInput":{"type":"object","properties":{"query":{"type":"string","minLength":1},"scenarioType":{"type":["string","null"]}},"required":["query"]},"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/scenario-from-query":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-scenario-from-query","summary":"Generate scenario from natural-language query","description":"Generates a structured simulation scenario from a natural-language query using the platform LLM (same generator as the New Simulation wizard's Generate from Query). Body: query, optional scenarioType. Proxies to data-service scenario-from-query. Returns the generated scenario plus a validation report; run it via POST simulations.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScenarioFromQueryInput"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Score rows against targets

> Batch counterfactual scoring: for each supplied row, the trained model finds the smallest set of changes that reaches the target outcome(s). Static trained twins only. Body: rows (≤500; keys name twin variables, a non-variable column becomes the row label), targets (\[{variable, value, matchMode?}]), maxChanges (default 3), constraints, webhookUrl. Returns 202 with runId; read the verdicts back via GET simulations/{runId}/score once completed.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"ScoreRowsInput":{"type":"object","properties":{"rows":{"type":"array","items":{"type":"object","additionalProperties":{}},"minItems":1,"maxItems":500,"description":"Rows to score; keys name twin variables (non-variable columns become row labels)"},"targets":{"type":"array","items":{"type":"object","properties":{"variable":{"type":"string"},"value":{},"matchMode":{"type":"string"}},"required":["variable"],"additionalProperties":{}},"minItems":1,"description":"Outcomes each row should reach: [{variable, value, matchMode?}]"},"maxChanges":{"type":"integer","minimum":1,"maximum":10,"description":"Most changes a counterfactual may make per row (default 3)"},"constraints":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"null"}],"description":"Per-variable constraints: {variable: {locked?, min?, max?, allowedValues?}}"},"webhookUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}],"description":"Optional URL called once when the run completes"}},"required":["rows","targets"]},"AsyncRunAccepted":{"type":"object","properties":{"data":{"type":"object","properties":{"runId":{"type":"string"},"status":{"type":"string","description":"pending until the run reaches a terminal status"},"createdAt":{"type":"string"},"links":{"type":"object","properties":{"self":{"type":"string","description":"Poll this until the status is terminal"},"results":{"type":"string","description":"Fetch when the run completes"}},"required":["self"]}},"required":["runId","status","links"],"description":"Envelope for asynchronous simulation runs. Poll links.self; fetch links.results when complete."}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/score":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-score","summary":"Score rows against targets","description":"Batch counterfactual scoring: for each supplied row, the trained model finds the smallest set of changes that reaches the target outcome(s). Static trained twins only. Body: rows (≤500; keys name twin variables, a non-variable column becomes the row label), targets ([{variable, value, matchMode?}]), maxChanges (default 3), constraints, webhookUrl. Returns 202 with runId; read the verdicts back via GET simulations/{runId}/score once completed.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoreRowsInput"}}}},"responses":{"202":{"description":"Accepted; poll the linked resource for completion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncRunAccepted"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get temporal dependencies

> Returns temporal dependencies for this version. If already stored on the version (platform MongoDB), returns that; otherwise computes them from the version's dataset via the data-service and returns the result (not persisted by this call).

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/temporal-dependencies":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-temporal-dependencies","summary":"Get temporal dependencies","description":"Returns temporal dependencies for this version. If already stored on the version (platform MongoDB), returns that; otherwise computes them from the version's dataset via the data-service and returns the result (not persisted by this call).","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Set temporal dependencies

> Stores temporal dependencies in the version (platform MongoDB). Body: object as returned by GET. Used to override or persist computed dependencies.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"TemporalDependenciesObjectSchema":{"type":"object","properties":{"prerequisites":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["prerequisites"]},"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/temporal-dependencies":{"put":{"operationId":"put-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-temporal-dependencies","summary":"Set temporal dependencies","description":"Stores temporal dependencies in the version (platform MongoDB). Body: object as returned by GET. Used to override or persist computed dependencies.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemporalDependenciesObjectSchema"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Train digital twin model

> Starts training for this version. Proxies to data-service create-digital-twin (orchestrator). Returns 202 with jobId (pipelineRunId or workflowId) and links (self, cancel). Poll jobs/{jobId} for status. Optional body: webhookUrl — POSTed once (best effort, unsigned) at the terminal state.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"WebhookBody":{"type":"object","properties":{"webhookUrl":{"type":["string","null"],"format":"uri"}}},"AsyncJobAccepted":{"type":"object","properties":{"data":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","description":"pending until the job reaches a terminal status"},"createdAt":{"type":"string"},"links":{"type":"object","properties":{"self":{"type":"string","description":"Poll this until the status is terminal"},"cancel":{"type":"string"}},"required":["self"]}},"required":["jobId","status","links"],"description":"Envelope for asynchronous pipeline work. Poll links.self until the job reaches a terminal status."}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/train":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-train","summary":"Train digital twin model","description":"Starts training for this version. Proxies to data-service create-digital-twin (orchestrator). Returns 202 with jobId (pipelineRunId or workflowId) and links (self, cancel). Poll jobs/{jobId} for status. Optional body: webhookUrl — POSTed once (best effort, unsigned) at the terminal state.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookBody"}}}},"responses":{"202":{"description":"Accepted; poll the linked resource for completion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncJobAccepted"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Check whether the model can assimilate new data

> Reports whether update-model would find new data and whether it can be assimilated incrementally: pending row counts, drift signals, and the recommended action (update vs retrain). Read-only and cheap — orchestrators should call this before firing update-model.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/update-eligibility":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-update-eligibility","summary":"Check whether the model can assimilate new data","description":"Reports whether update-model would find new data and whether it can be assimilated incrementally: pending row counts, drift signals, and the recommended action (update vs retrain). Read-only and cheap — orchestrators should call this before firing update-model.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Assimilate new data into the trained model

> Folds data added to the version's backing source or dataset since the last train/update into the trained model incrementally — no retrain. No request body: new data reaches the model by extending or syncing the source first, then calling this. Requires lifecycleState trained. The job SUCCEEDS with a terminal status rather than failing: \`committed\` (new rows folded in), \`up\_to\_date\` (nothing new), or \`retrain\_required\` (the model cannot take these rows incrementally — the data drifted structurally, or the twin kind does not assimilate: static and temporal twins do out of the box, panel twins need the v2 panel engine, multi-environment-static does not; metadata.reasons says which). One update runs per version at a time; a concurrent call returns 409. Check GET update-eligibility first to know the likely outcome without starting a job. Optional body: webhookUrl — POSTed once (best effort, unsigned) at the terminal state.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"WebhookBody":{"type":"object","properties":{"webhookUrl":{"type":["string","null"],"format":"uri"}}},"AsyncJobAccepted":{"type":"object","properties":{"data":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","description":"pending until the job reaches a terminal status"},"createdAt":{"type":"string"},"links":{"type":"object","properties":{"self":{"type":"string","description":"Poll this until the status is terminal"},"cancel":{"type":"string"}},"required":["self"]}},"required":["jobId","status","links"],"description":"Envelope for asynchronous pipeline work. Poll links.self until the job reaches a terminal status."}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/update-model":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-update-model","summary":"Assimilate new data into the trained model","description":"Folds data added to the version's backing source or dataset since the last train/update into the trained model incrementally — no retrain. No request body: new data reaches the model by extending or syncing the source first, then calling this. Requires lifecycleState trained. The job SUCCEEDS with a terminal status rather than failing: `committed` (new rows folded in), `up_to_date` (nothing new), or `retrain_required` (the model cannot take these rows incrementally — the data drifted structurally, or the twin kind does not assimilate: static and temporal twins do out of the box, panel twins need the v2 panel engine, multi-environment-static does not; metadata.reasons says which). One update runs per version at a time; a concurrent call returns 409. Check GET update-eligibility first to know the likely outcome without starting a job. Optional body: webhookUrl — POSTed once (best effort, unsigned) at the terminal state.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookBody"}}}},"responses":{"202":{"description":"Accepted; poll the linked resource for completion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncJobAccepted"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"409":{"$ref":"#/components/responses/409"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get variable roles

> Returns variable roles (input/target/etc.) for this version. If version.variableRoles exists in platform MongoDB, returns it; otherwise computes them from the version's dataset via the data-service (not persisted).

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/variable-roles":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-variable-roles","summary":"Get variable roles","description":"Returns variable roles (input/target/etc.) for this version. If version.variableRoles exists in platform MongoDB, returns it; otherwise computes them from the version's dataset via the data-service (not persisted).","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Set variable roles

> Stores variable roles on the version (platform MongoDB). Body: record of variable role assignments. Overwrites existing variableRoles. Roles naming a variable outside the version's input fields are dropped, so the stored roles always describe the variables the version was trained on; the stored value is what the response returns.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"VariableRolesSchema":{"type":"object","properties":{"sources":{"type":"array","items":{"type":"string"}},"targets":{"type":"array","items":{"type":"string"}}},"required":["sources","targets"]},"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/variable-roles":{"put":{"operationId":"put-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-variable-roles","summary":"Set variable roles","description":"Stores variable roles on the version (platform MongoDB). Body: record of variable role assignments. Overwrites existing variableRoles. Roles naming a variable outside the version's input fields are dropped, so the stored roles always describe the variables the version was trained on; the stored value is what the response returns.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariableRolesSchema"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Resolve an environment group against a version

> Multi-environment (panel) twins: turns a group's declarative rule into the concrete environments it matches on this version. Send exactly one of \`groupId\` (a group saved on the twin) or \`definition\` (an ad-hoc rule, resolved without saving). Returns environmentColumns, the matching combos, their envKeys, sampleSize, totalEnvCount (environments this version has causal-discovery evidence for), unresolvedEnvCount, and — for statFilters rules — matchedBeforeEvidenceFilter, how many environments the filter selected in the data before intersecting with that evidence.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"ResolveEnvironmentGroupInput":{"type":"object","properties":{"groupId":{"type":"string","description":"Id of a saved environment group on this twin"},"definition":{"$ref":"#/components/schemas/EnvironmentGroupDefinitionSchema","description":"An ad-hoc membership rule to resolve without saving it"}}},"EnvironmentGroupDefinitionSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["columnValues","environments","statFilters"]},"columnValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}]},"environments":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},{"type":"null"}]},"statFilters":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"},{"type":"null"}]},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}]}},"required":["mode"]},"EnvStatFilterGroupSchema":{"type":"object","properties":{"booleanOperator":{"type":"string","enum":["AND","OR"]},"filters":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/EnvStatFilterSchema"},{"$ref":"#/components/schemas/EnvStatFilterGroupSchema"}]}}},"required":["booleanOperator","filters"]},"EnvStatFilterSchema":{"type":"object","properties":{"column":{"type":"string"},"comparisonOperator":{"type":"string"},"value":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":["string","number","boolean"]}}]},"reduce":{"anyOf":[{"$ref":"#/components/schemas/EnvStatReduceEnum"},{"type":"null"}]}},"required":["column","comparisonOperator","value"]},"EnvStatReduceEnum":{"type":"string","enum":["value","mean","min","max","any"]},"ResolvedEnvironmentGroupEnvelope":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResolvedEnvironmentGroupSchema"}},"required":["data"]},"ResolvedEnvironmentGroupSchema":{"type":"object","properties":{"groupId":{"type":["string","null"]},"name":{"type":["string","null"]},"environmentColumns":{"type":"array","items":{"type":"string"}},"environments":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},"envKeys":{"type":"array","items":{"type":"string"}},"sampleSize":{"type":"number"},"totalEnvCount":{"type":"number"},"unresolvedEnvCount":{"type":"number","default":0},"matchedBeforeEvidenceFilter":{"type":["number","null"]},"unresolvable":{"anyOf":[{"$ref":"#/components/schemas/GroupUnresolvableSchema"},{"type":"null"}]}},"required":["environmentColumns","environments","envKeys","sampleSize","totalEnvCount"]},"GroupUnresolvableSchema":{"type":"object","properties":{"reason":{"type":"string","enum":["noEnvironmentColumns","unknownEnvironmentColumn","shapeMismatch","unknownFilterColumn","filterQueryFailed","noEvidence"]},"message":{"type":"string"},"columns":{"type":"array","items":{"type":"string"},"default":[]}},"required":["reason","message"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/environment-groups/resolve":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-environment-groups-resolve","summary":"Resolve an environment group against a version","description":"Multi-environment (panel) twins: turns a group's declarative rule into the concrete environments it matches on this version. Send exactly one of `groupId` (a group saved on the twin) or `definition` (an ad-hoc rule, resolved without saving). Returns environmentColumns, the matching combos, their envKeys, sampleSize, totalEnvCount (environments this version has causal-discovery evidence for), unresolvedEnvCount, and — for statFilters rules — matchedBeforeEvidenceFilter, how many environments the filter selected in the data before intersecting with that evidence.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveEnvironmentGroupInput"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolvedEnvironmentGroupEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Query environments by data statistics

> Panel twins: resolves a stat-filter group to the concrete environments it matches — filter on ANY twin column, not just the environment columns, via per-environment aggregates (mean/min/max), constant values, or categorical presence (any). Returns environmentColumns, the matching environments as {column: value} combos, their envKeys, sampleSize, and totalEnvCount. Feed the combos to graph/slice or scope simulations with them. Example: {statFilters: {booleanOperator: "AND", filters: \[{column: "revenue", reduce: "mean", comparisonOperator: ">", value: 400}]}}.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"ResolveEnvironmentsInput":{"type":"object","properties":{"statFilters":{"type":"object","additionalProperties":{},"description":"A filter group: {booleanOperator: AND | OR, filters: [{column, comparisonOperator, value, reduce}]} — reduce is value (constant per environment), mean/min/max (numeric aggregate), or any (at least one matching row); groups nest"}},"required":["statFilters"]},"ResolvedEnvironmentGroupEnvelope":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResolvedEnvironmentGroupSchema"}},"required":["data"]},"ResolvedEnvironmentGroupSchema":{"type":"object","properties":{"groupId":{"type":["string","null"]},"name":{"type":["string","null"]},"environmentColumns":{"type":"array","items":{"type":"string"}},"environments":{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},"envKeys":{"type":"array","items":{"type":"string"}},"sampleSize":{"type":"number"},"totalEnvCount":{"type":"number"},"unresolvedEnvCount":{"type":"number","default":0},"matchedBeforeEvidenceFilter":{"type":["number","null"]},"unresolvable":{"anyOf":[{"$ref":"#/components/schemas/GroupUnresolvableSchema"},{"type":"null"}]}},"required":["environmentColumns","environments","envKeys","sampleSize","totalEnvCount"]},"GroupUnresolvableSchema":{"type":"object","properties":{"reason":{"type":"string","enum":["noEnvironmentColumns","unknownEnvironmentColumn","shapeMismatch","unknownFilterColumn","filterQueryFailed","noEvidence"]},"message":{"type":"string"},"columns":{"type":"array","items":{"type":"string"},"default":[]}},"required":["reason","message"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/environments/resolve":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-environments-resolve","summary":"Query environments by data statistics","description":"Panel twins: resolves a stat-filter group to the concrete environments it matches — filter on ANY twin column, not just the environment columns, via per-environment aggregates (mean/min/max), constant values, or categorical presence (any). Returns environmentColumns, the matching environments as {column: value} combos, their envKeys, sampleSize, and totalEnvCount. Feed the combos to graph/slice or scope simulations with them. Example: {statFilters: {booleanOperator: \"AND\", filters: [{column: \"revenue\", reduce: \"mean\", comparisonOperator: \">\", value: 400}]}}.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveEnvironmentsInput"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolvedEnvironmentGroupEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Get fixed subgraph

> Returns the version's fixed subgraph: relationships (edges pinned as present) and antiRelationships (edges forbidden). Empty arrays when nothing is fixed.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/graph/fixed":{"get":{"operationId":"get-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-graph-fixed","summary":"Get fixed subgraph","description":"Returns the version's fixed subgraph: relationships (edges pinned as present) and antiRelationships (edges forbidden). Empty arrays when nothing is fixed.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Patch fixed subgraph

> Applies incremental domain knowledge to the fixed subgraph. Body: addEdges (\[{source, target}]) pins edges as present; removeEdges (\[{source, target}]) forbids them. Discovery and training respect the fixed subgraph on their next run. Returns the updated fixedSubGraph.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"PatchFixedGraphInput":{"type":"object","properties":{"addEdges":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"target":{"type":"string"}},"required":["source","target"]}},"removeEdges":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"target":{"type":"string"}},"required":["source","target"]}}},"required":["addEdges","removeEdges"]},"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/graph/fixed":{"patch":{"operationId":"patch-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-graph-fixed","summary":"Patch fixed subgraph","description":"Applies incremental domain knowledge to the fixed subgraph. Body: addEdges ([{source, target}]) pins edges as present; removeEdges ([{source, target}]) forbids them. Discovery and training respect the fixed subgraph on their next run. Returns the updated fixedSubGraph.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchFixedGraphInput"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```

## Aggregate the causal graph over an environment subset

> Panel twins: re-aggregates the causal graph over a subset of environments and returns that subset's adjacency — causalGraph (edges with strength and cross-environment agreement), nodes, envCount, sampleSize, totalEnvCount, and the agreementThreshold used. The subset is given either inline or by reference. Inline, \`mode\` picks the rule: \`environments\` (exact combos, each {column: value}), \`columnValues\` (allowed values per environment column), or \`statFilters\` (select environments by per-environment aggregates). By reference, send \`{groupId}\` naming a saved environment group on this twin (see GET .../environment-groups) and, optionally, an \`agreementThreshold\` that overrides the one stored on the group for this call. agreementThreshold (0-1, default 0.5) sets the share of environments an edge must hold in to survive. Computed from stored causal-discovery evidence — no retraining, read-only. 422 when the subset matches no environments with evidence; POST .../environment-groups/resolve answers the same question without the 422 when you only want the membership. List the environments first via GET .../environments.

```json
{"openapi":"3.1.0","info":{"title":"RootCause Public API","version":"1.0.0"},"tags":[{"name":"Digital Twins"}],"servers":[{"url":"https://sandbox.rootcause.ai","description":"Sandbox"},{"url":"https://platform.rootcause.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local development"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"An API key (pk_...) created on the Organisation API page, or an OAuth access token. Every operation requires one."}},"schemas":{"GraphSliceInput":{"anyOf":[{"type":"object","properties":{"mode":{"type":"string","enum":["columnValues","environments","statFilters"],"description":"How the environment subset is defined"},"columnValues":{"anyOf":[{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}},{"type":"null"}],"description":"columnValues mode: allowed values per environment column; an unconstrained column admits all values"},"environments":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{"type":"string"}}},{"type":"null"}],"description":"environments mode: exact environment combos, each {column: value}"},"statFilters":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"null"}],"description":"statFilters mode: select environments by per-environment aggregates over any twin column"},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}],"description":"Share of environments (0-1) a relationship must hold in to keep an edge (default 0.5)"}},"required":["mode"]},{"type":"object","properties":{"groupId":{"type":"string","description":"Id of a saved environment group on this twin; its stored definition supplies the subset"},"agreementThreshold":{"anyOf":[{"type":"number","minimum":0,"maximum":1},{"type":"null"}],"description":"Overrides the agreementThreshold stored on the group for this call only"}},"required":["groupId"]}]},"UnspecifiedEnvelope":{"type":"object","properties":{"data":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"object","additionalProperties":{}},{"type":"array","items":{}}],"description":"Payload not declared in this repo"}},"required":["data"]}},"responses":{"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"429":{"description":"Too Many Requests; the response carries Retry-After","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"}},"required":["type","title","status","detail"]}}}}}},"paths":{"/api/v1/workspaces/{wsId}/digital-twins/{id}/versions/{vId}/graph/slice":{"post":{"operationId":"post-api-v1-workspaces-{wsId}-digital-twins-{id}-versions-{vId}-graph-slice","summary":"Aggregate the causal graph over an environment subset","description":"Panel twins: re-aggregates the causal graph over a subset of environments and returns that subset's adjacency — causalGraph (edges with strength and cross-environment agreement), nodes, envCount, sampleSize, totalEnvCount, and the agreementThreshold used. The subset is given either inline or by reference. Inline, `mode` picks the rule: `environments` (exact combos, each {column: value}), `columnValues` (allowed values per environment column), or `statFilters` (select environments by per-environment aggregates). By reference, send `{groupId}` naming a saved environment group on this twin (see GET .../environment-groups) and, optionally, an `agreementThreshold` that overrides the one stored on the group for this call. agreementThreshold (0-1, default 0.5) sets the share of environments an edge must hold in to survive. Computed from stored causal-discovery evidence — no retraining, read-only. 422 when the subset matches no environments with evidence; POST .../environment-groups/resolve answers the same question without the 422 when you only want the membership. List the environments first via GET .../environments.","tags":["Digital Twins"],"parameters":[{"name":"wsId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: wsId"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: id"},{"name":"vId","in":"path","required":true,"schema":{"type":"string"},"description":"Path parameter: vId"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GraphSliceInput"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnspecifiedEnvelope"}}}},"400":{"$ref":"#/components/responses/400"},"401":{"$ref":"#/components/responses/401"},"403":{"$ref":"#/components/responses/403"},"404":{"$ref":"#/components/responses/404"},"422":{"$ref":"#/components/responses/422"},"429":{"$ref":"#/components/responses/429"},"500":{"$ref":"#/components/responses/500"}}}}}}
```
