---
title: "What-if parametric sweep"
method: POST
path: "/v1/simulate/what-if"
tags: ["What-If Analysis"]
---

# What-if parametric sweep

`POST /v1/simulate/what-if`

## Request

- Base URL: `https://api.algenta.ai`
- URL: `https://api.algenta.ai/v1/simulate/what-if`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Vary one variable parameter across a range and see how outcomes change. All steps run in parallel via Mojo worker pool. Returns a sweep with mean, percentiles, and probability of loss at each step. Automatically computes sensitivity direction and elasticity.

## Request body

- WhatIfRequest: Inline what-if request (no stored run needed).
  - `request` union, required: Base simulation request
    - SimulateRequestAuto: Auto-mode simulation request — minimal setup, engine infers distributions.
      - `mode` 'auto', required
      - `scenario` AutoScenario, required
        - `name` string, nullable
        - `variables` object, required
        - `objective` 'maximize_net_value' | 'maximize_revenue' | 'minimize_cost' | 'minimize_risk' | 'maximize_score', required
      - `runs` integer
      - `seed` integer, nullable
      - `simulation_model` 'monte_carlo' | 'qmc_sobol' | 'lhs' | 'bootstrap' | 'scenario' | 'sensitivity' | 'mcmc' | 'decision_tree' | 'time_series' | 'compare' | 'importance_sampling': Which simulation algorithm to use. ALL run natively in Mojo — zero Python bottlenecks.
      - `bootstrap_config` BootstrapConfig: Config for engine_type='bootstrap' — non-parametric resampling.
        - `historical_data` number[], required
        - `statistic` string: Statistic to compute on each resample. One of: mean, median, std, variance, sum, min, max, sharpe, percentile_5, percentile_25, percentile_75, percentile_95, range, cv
        - `confidence_level` number
      - `scenario_config` ScenarioConfig: Config for engine_type='scenario' — discrete weighted scenarios.
        - `scenarios` ScenarioItem[], required
          - `name` string, required
          - `probability` number, required
          - `variables` object
          - `objective_function` string, nullable
      - `sensitivity_config` SensitivityConfig: Config for engine_type='sensitivity' — sensitivity analysis.
        - `method` string: tornado | sobol | both
    - SimulateRequestExpert: Expert-mode simulation request — full distribution and objective control.
      - `mode` 'expert', required
      - `simulation` ExpertSimulation, required: Universal simulation specification. No restrictions on domain, variable count, or expression complexity. Works for any industry and data type. objective_function — complete function reference: Arithmetic: +, -, *, /, ^ (power), % (mod) Standard: sqrt(x), exp(x), ln(x), log(x), log10(x), log2(x), log1p(x), expm1(x), abs(x), floor(x), ceil(x), round(x) Min/Max: min(a,b), max(a,b), clip(v,lo,hi) Conditional: if(cond>0, then_val, else_val) Trigonometry: sin(x), cos(x), tan(x), asin(x), acos(x), atan(x) atan2(y,x), sinh(x), cosh(x), tanh(x) Special: erf(x), erfc(x), gamma(x), lgamma(x), sign(x), hypot(a,b) Statistical: norm_cdf(x), norm_pdf(x), norm_ppf(p), t_cdf(x, df), chi2_cdf(x, df), logistic(x), logit(x) Combinatorics: factorial(n), comb(n,k), perm(n,k) Sequences: fibonacci(n), fib(n), fib_ratio(n) = F(n)/F(n-1) Financial: npv(rate,cf0,cf1,...), pmt(rate,n,pv), fv(rate,n,pmt,pv), pv(rate,n,pmt), annuity(rate,n), duration(rate,n) Constants: c (speed of light), G (gravity), g (9.81 m/s²), kB (Boltzmann), NA (Avogadro), R (gas), pi, e, phi Multi-output: separate objectives with | e.g. "net_profit | risk_score | irr" Variables: any variable name from the variables list as a symbol Examples: "revenue - cost" "max(0, sales * margin - fixed_cost)" "npv(0.1, -capex, cf1, cf2, cf3, cf4, cf5)" "norm_cdf((mu - threshold) / sigma)" "mass * g * height" # kinetic/potential energy "fibonacci(growth_stage)" # Fibonacci growth model "revenue - cost | revenue / cost | norm_cdf(revenue - target)" # multi-output
        - `variables` VariableSpec[], required
          - `name` string, required
          - `distribution` 'normal' | 'uniform' | 'triangular' | 'lognormal' | 'fixed' | 'discrete' | 'categorical' | 'beta' | 'exponential' | 'weibull' | 'gamma' | 'pert' | 'bernoulli' | 'poisson' | 'student_t' | 'cauchy' | 'laplace' | 'pareto' | 'gumbel' | 'rayleigh' | 'arcsine' | 'logistic' | 'halfnormal' | 'vonmises' | 'neg_binomial' | 'hypergeometric' | 'negative_binomial', required: Universal distribution library — no restrictions on domain or data type. Applicable to any industry: finance, medical, manufacturing, aerospace, defense, energy, hospitality, insurance, pharma, supply chain, and more.
          - `params` DistributionParams, required
            - `mean` number, nullable
            - `std` number, nullable
            - `low` number, nullable
            - `high` number, nullable
            - `mode` number, nullable
            - `value` number, nullable
            - `alpha` number, nullable
            - `beta` number, nullable
            - `rate` number, nullable
            - `lambda` number, nullable
            - `shape` number, nullable
            - `scale` number, nullable
            - `likely` number, nullable
            - `gamma` number, nullable
            - `p` number, nullable
            - `values` number[], nullable
            - `probabilities` number[], nullable
          - `unit` string, nullable: Short-hand unit string: 'USD', 'BTC', '%', 'bps', 'days', 'Pa', etc.
          - `unit_spec` UnitSpec: Universal unit specification — supports any numeric domain. Short-hand strings also accepted anywhere a UnitSpec is expected: "USD" → currency/USD (2 decimal places) "BTC" → crypto/BTC (8 decimal places, satoshi-aware) "ETH" → crypto/ETH (18 decimals, wei-aware) "%" → percentage (scale × 100 for display) "bps" → basis points (scale × 10,000 for display) "days" → duration in days "Pa" / "kg" → SI unit (scientific notation for tiny/huge values) "probability" → strictly [0,1] validated "count" → non-negative integer-like Full dict form: { "type": "currency", # unit category "code": "USD", # unit identifier "precision": 2, # display decimal places (None = auto) "scale": 1.0, # multiply raw value for display (e.g. 100 for 0→1 % → 0→100%) "format": "compact", # standard | compact | scientific "base_unit": "satoshi", # sub-unit label (informational) "sim_scale": 1.0 # divide input by this before simulation }
            - `type` string: Unit category: currency | crypto | date | duration | percentage | bps | scientific | si | count | probability | custom | raw
            - `code` string: Unit identifier: ISO 4217 currency, crypto ticker, SI symbol, etc.
            - `precision` integer, nullable: Display decimal places. None = auto-inferred from type/code.
            - `scale` number: Multiply raw simulation output by this for display (e.g. 100 for percentage).
            - `format` string: Display format: standard | compact ($1.2M) | scientific (1.23e-9)
            - `base_unit` string: Sub-unit label (informational). E.g. 'satoshi' for BTC, 'wei' for ETH.
            - `sim_scale` number: Divide input params by this before simulation. E.g. sim_scale=1e8 if BTC inputs are in satoshis, converts to whole BTC for Mojo.
          - `description` string, nullable
          - `domain_hint` string, nullable: Optional domain hint e.g. 'time_to_failure', 'patient_recovery_days', 'material_yield_strength'
          - `labels` string[], nullable: For categorical/discrete: human-readable labels for each outcome index
        - `correlations` CorrelationSpec[]
          - `variables` string[], required
          - `coefficient` number, required
        - `objective_function` string, nullable: Expression evaluated each scenario. Supports all math functions. Multi-output: separate with | pipe character. Example: 'revenue - cost | (revenue - cost) / revenue * 100 | min(cash_flow, 0)'
        - `scoring` ScoringWeights
          - `expected_value` number
          - `downside_risk` number
        - `domain` string, nullable: Industry/domain hint: finance, medical, manufacturing, aerospace, defense, etc.
        - `domain_template` string, nullable: Name of predefined domain template used (for reference)
        - `output_labels` string[], nullable: Labels for multi-output objectives (matches | separator count)
        - `output_units` string[], nullable: Physical/currency units for each output. E.g. ['USD', '%', 'years']
        - `output_unit_specs` UnitSpec[], nullable: Full UnitSpec per output objective (matches | separator count). Enables formatted_result in the response with currency symbols, compact notation ($1.2M), scientific notation (1.23e-9 Pa), etc. Example: [{'type':'currency','code':'USD','format':'compact'}, {'type':'percentage'}]
          - `type` string: Unit category: currency | crypto | date | duration | percentage | bps | scientific | si | count | probability | custom | raw
          - `code` string: Unit identifier: ISO 4217 currency, crypto ticker, SI symbol, etc.
          - `precision` integer, nullable: Display decimal places. None = auto-inferred from type/code.
          - `scale` number: Multiply raw simulation output by this for display (e.g. 100 for percentage).
          - `format` string: Display format: standard | compact ($1.2M) | scientific (1.23e-9)
          - `base_unit` string: Sub-unit label (informational). E.g. 'satoshi' for BTC, 'wei' for ETH.
          - `sim_scale` number: Divide input params by this before simulation. E.g. sim_scale=1e8 if BTC inputs are in satoshis, converts to whole BTC for Mojo.
      - `runs` integer
      - `seed` integer, nullable
      - `simulation_model` 'monte_carlo' | 'qmc_sobol' | 'lhs' | 'bootstrap' | 'scenario' | 'sensitivity' | 'mcmc' | 'decision_tree' | 'time_series' | 'compare' | 'importance_sampling': Which simulation algorithm to use. ALL run natively in Mojo — zero Python bottlenecks.
      - `bootstrap_config` BootstrapConfig: Config for engine_type='bootstrap' — non-parametric resampling.
        - `historical_data` number[], required
        - `statistic` string: Statistic to compute on each resample. One of: mean, median, std, variance, sum, min, max, sharpe, percentile_5, percentile_25, percentile_75, percentile_95, range, cv
        - `confidence_level` number
      - `scenario_config` ScenarioConfig: Config for engine_type='scenario' — discrete weighted scenarios.
        - `scenarios` ScenarioItem[], required
          - `name` string, required
          - `probability` number, required
          - `variables` object
          - `objective_function` string, nullable
      - `mcmc_config` MCMCConfig: Config for engine_type='mcmc' — Metropolis-Hastings Bayesian MCMC.
        - `observed_data` number[], required
        - `parameter_priors` object: Dict of param_name → {distribution, params}. Auto-inferred from data if empty. Example: {'mean': {'distribution': 'normal', 'params': {'mean': 500000, 'std': 100000}}}
        - `likelihood` string: Likelihood model: normal | lognormal | poisson
        - `chains` integer
        - `burn_in` integer
      - `sensitivity_config` SensitivityConfig: Config for engine_type='sensitivity' — sensitivity analysis.
        - `method` string: tornado | sobol | both
      - `importance_sampling_config` ImportanceSamplingConfig: Config for engine_type='importance_sampling' — exponential tilting for rare tail events. Use when you need accurate estimates of very low-probability events (e.g. 1-in-10,000 loss scenarios) without running millions of MC trials. The engine shifts sampling mass toward the target tail using exponential tilting (θ optimal tilt), then corrects back with likelihood ratio weights. Reports: tail_probability, tail_probability_se, cvar_tail, ESS, variance_reduction_factor.
        - `target_threshold` number, required: The rare event level. E.g. -500000 for a $500k loss, or 2.5 for an extreme gain.
        - `tail_direction` string: 'lower' for loss events (outcome < threshold), 'upper' for extreme gains (outcome > threshold).
        - `tilt_variable` string, nullable: Name of the normal-distributed variable to apply exponential tilting to. Auto-detects the highest-variance normal variable if omitted.
        - `tilt_sigma` number: Override the tilt parameter θ directly (0 = auto-compute from threshold). Advanced use only.
      - `decision_tree_config` DecisionTreeConfig: Config for engine_type='decision_tree' — multi-layered decisions with branches. Example (2-level tree): nodes: [ { id: "launch_decision", type: "decision", name: "Launch Product?", branches: [ { id: "launch_yes", type: "chance", name: "Launch", probability: 1.0, branches: [ { id: "accept", type: "terminal", name: "Market Accepts", probability: 0.7, objective_function: "revenue - launch_cost" }, { id: "reject", type: "terminal", name: "Market Rejects", probability: 0.3, variables: {"revenue": 0}, objective_function: "-launch_cost" } ] } ] } ]
        - `nodes` DecisionNode[], required: Root nodes of the decision tree. Multiple roots = parallel independent decisions.
          - `id` string, required
          - `type` string: Node type: decision | chance | terminal
          - `name` string
          - `probability` number: Branch probability (for chance nodes). All siblings should sum to 1.0.
          - `condition` string, nullable: Optional expression condition for this branch to be active
          - `variables` object: Variable overrides for this branch. Scalar value → treated as fixed distribution. Dict → full VariableSpec override {distribution, params}.
          - `objective_function` string, nullable: Expression override for this node. Inherits top-level if not set.
          - `branches` DecisionNode[]: Child branches. Empty = terminal node.
        - `max_depth` integer: Maximum allowed tree depth
      - `time_series_config` TimeSeriesConfig: Config for engine_type='time_series' — multi-horizon stochastic path simulation. Supported models: gbm — Geometric Brownian Motion ou — Ornstein-Uhlenbeck mean-reversion arithmetic — Arithmetic Brownian Motion compound — Compound return custom — Expression-driven path Granularities: ms, s, min, h, day, week, month, quarter, year
        - `model` string: Path model: gbm | ou | arithmetic | compound | custom
        - `initial_value` number, required: Starting value of the process (e.g. current stock price, balance, etc.)
        - `horizons` integer[]: Time steps at which to record distributions. E.g. [1,3,6,12] for 1/3/6/12 months.
        - `granularity` string: Time unit per step. One of: ms, s, min, h, day, week, month, quarter, year. All drift/vol parameters assumed annualized unless granularity='custom'.
        - `drift` union: Annualized drift / expected return. Float shorthand or StochasticParam for uncertain drift. GBM: annual log-return. OU: not used (use long_run_mean). Compound: annual return.
          - StochasticParam: A simulation parameter that is itself stochastic (drawn fresh for each path). Use for uncertain drift, volatility, or any time-series parameter.
            - `type` string: fixed | normal | uniform | lognormal
            - `value` number: Fixed value (for type='fixed')
            - `mean` number: Mean (for type='normal' or 'lognormal')
            - `std` number: Std dev (for type='normal' or 'lognormal')
            - `low` number: Lower bound (for type='uniform')
            - `high` number: Upper bound (for type='uniform')
          - number
        - `volatility` union: Annualized volatility (σ). Float or StochasticParam.
          - StochasticParam: A simulation parameter that is itself stochastic (drawn fresh for each path). Use for uncertain drift, volatility, or any time-series parameter.
            - `type` string: fixed | normal | uniform | lognormal
            - `value` number: Fixed value (for type='fixed')
            - `mean` number: Mean (for type='normal' or 'lognormal')
            - `std` number: Std dev (for type='normal' or 'lognormal')
            - `low` number: Lower bound (for type='uniform')
            - `high` number: Upper bound (for type='uniform')
          - number
        - `autocorrelation` number: AR(1) autocorrelation coefficient for innovations (0 = i.i.d., >0 = trending, <0 = mean-reverting noise)
        - `long_run_mean` number, nullable: OU model: long-run mean (μ∞). Defaults to initial_value.
        - `mean_reversion_speed` number: OU model: speed of mean reversion (θ). Higher = faster pull to mean.
        - `path_expression` string, nullable: Custom model: Python expression for next step value. Variables: value, t, dt, drift, vol, z, initial. Example: 'value * exp((drift - 0.5*vol**2)*dt + vol*dt**0.5*z)'
        - `fan_chart_percentiles` integer[]: Percentile levels to include in the fan chart output at each horizon.
        - `output_paths` boolean: Include sample path data in response (for fan chart visualization). Adds ~50 paths.
        - `n_sample_paths` integer: Number of sample paths to include when output_paths=True.
      - `include_charts` boolean: Include pre-computed Vega-Lite chart specs in the response. When true, adds 'charts' dict with histogram, CDF, tornado (if sensitivity), fan_chart (if time_series). Ready to pass to vega-embed for instant rendering. Adds ~5ms to response time.
      - `include_histogram` boolean: Include pre-computed 50-bin histogram data (lighter than full chart spec). Adds 'histogram_data' to response. Useful for quick distribution preview.
  - `variable` string, required: Variable name to sweep
  - `param` string: Which parameter to vary: mean, std, low, high, mode, value
  - `range_pct` number: Sweep range as fraction of base value (e.g. 0.30 = ±30%)
  - `n_steps` integer: Number of steps (odd number recommended for symmetric sweep)
  - `runs_per_step` integer: Monte Carlo runs per step. Lower for faster response.

## Response `200`

Successful Response

- WhatIfResponse: Full what-if sweep result.
  - `variable` string, required
  - `n_steps` integer, required
  - `range_low` number, required
  - `range_high` number, required
  - `param_changed` string, required
  - `steps` WhatIfStep[], required
    - `step` integer, required
    - `value` number, required
    - `label` string, required
    - `mean` number, required
    - `std` number, required
    - `p5` number, required
    - `p25` number, required
    - `p50` number, required
    - `p75` number, required
    - `p95` number, required
    - `probability_of_loss` number, required
    - `score` number, nullable
  - `increasing_direction` string, required
  - `sensitivity_label` string, required
  - `elasticity` number, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/codna/apis/algenta-api.md) · [All operations](https://skmtc.dev/codna/apis/algenta-api/llms.txt) · [OpenAPI document](https://skmtc.dev/codna/apis/algenta-api/revisions/35d30f84a5df?raw)
