---
title: "Rebuild Model"
method: POST
path: "/v1/models/{model}/rebuild"
tags: ["Models"]
---

# Rebuild Model

`POST /v1/models/{model}/rebuild`

## Request

- Base URL: `https://api.ensemble.markets` (the document declares no server; this is the origin it was published from)
- URL: `https://api.ensemble.markets/v1/models/{model}/rebuild`
- Auth: HTTP bearer

Regenerate the model's implementation.

With `prompt`, the model is rewritten to the new description. With `script`, your implementation replaces the stored one (validated and smoke-run, no generation). With neither, the stored prompt is used again: a failed model is rebuilt from its own failure (the generator sees the script that broke and the error), a built model is simply regenerated. A built model keeps serving its current implementation until the new one succeeds; existing runs keep the `script_hash` they ran under. Answers 202 with `run.kind` rebuild; the model's `run` becomes null when work ends. Metered like a create. 409 `rebuild_conflict` while a build owns the model.

## Path parameters

- `model` string, required: Model ID (model_... or legacy m-...), slug, symbol or exact name

## Request body

- ModelRebuildRequest: Regenerate a model's implementation (LLM + sandbox). With `prompt`, the model is rewritten to the new description. Without it, the stored prompt is used again: on a failed model the generator is handed the script that failed and the error it died on; on a built model the implementation is simply regenerated (for example at a higher effort). The model keeps its ID and URL, and a built model keeps serving its current implementation until the new one succeeds.
  - `prompt` string, nullable: New description. Omit to rebuild from the stored prompt. Members may change; a model can never hold one of its own parents.
  - `script` string, nullable: Your own implementation instead of a prompt. Validated against the same contract as generated code, smoke-run in the sandbox, and stored verbatim. Billed as a build without generation tokens.
  - `name` string, nullable: Rename the model (defaults to keeping the current name)
  - `symbol` string, nullable: Change the model symbol (defaults to keeping the current one)
  - `effort` 'min' | 'mid' | 'max', nullable: How hard the generator works. min (default, all plans): a fast single-shot build. mid (Hobby and Business): a stronger model plus a fidelity review of the script against your description. max (Business): additionally inspects results and refines the implementation. Higher effort bills more per token. Defaults to the effort of the previous build when the prompt is omitted, otherwise min.
  - `start_date` string, date, nullable: Where the default view of the history begins (YYYY-MM-DD). The full history is always computed and `full_history=true` on any history read reveals it; omission lets start_rule choose. The backtest's start date is an execution input, separate from this view window. Omitted: a new prompt is read for a date or period, otherwise the stored setting is kept.
  - `start_rule` 'two_members' | 'all_members' | 'first_member', nullable: Where the default view begins when no start_date is set. two_members (default): the first day two universe members have data, the earliest a rebalance between them means anything. all_members: the first day every member has data. first_member: the first day any member has data, the full history. Omitted: the stored rule is kept.

## Response `202`

Successful Response

- Model
  - `id` string, required: Model ID (model_... or legacy m-...)
  - `name` string, nullable: May be null if the build failed before naming
  - `symbol` string, nullable: May be null if the build failed before naming
  - `status` 'building' | 'active' | 'updating' | 'paused' | 'blocked' | 'failed', required: building: no results yet; active: results served and refreshed nightly; updating: a rebuild or refresh is running (results keep serving); blocked: updates await a failed or unavailable dependency; paused: results served, nightly refresh off; failed: the build never produced a usable model
  - `run` ModelActivity: What is running against the model right now. Null when idle.
    - `kind` 'build' | 'rebuild' | 'run', required: build: first build; rebuild: new implementation from a prompt or script; run: the stored script against new market data (a default run that will go live)
    - `status` 'queued' | 'running', required
    - `stage` string, required: Human-readable current stage, e.g. 'Backtesting'
    - `stage_id` 'n1_security_screening' | 'n1b_universe_resolution' | 'n2_code_generation' | 'n3_code_validation' | 'n4_modal_execution' | 'n5_result_qa', nullable: Pipeline stage id; null for a run
    - `attempt` integer
    - `max_attempts` integer
    - `started_at` string, date-time, nullable
    - `updated_at` string, date-time, nullable
    - `stages` ModelActivityStage[]: Per-stage detail for a build or rebuild; empty for a run
      - `id` 'n1_security_screening' | 'n1b_universe_resolution' | 'n2_code_generation' | 'n3_code_validation' | 'n4_modal_execution' | 'n5_result_qa', required
      - `status` 'pending' | 'running' | 'completed' | 'error', required
      - `attempt` integer
      - `duration_seconds` number, nullable
  - `warning` string, nullable: Something went wrong without changing the status: a failed rebuild, a paused auto-update, or overdue data
  - `depth` integer: 0 when the model holds assets only; otherwise one more than its deepest member
  - `structure` ModelStructure: What the model's whole tree resolves to.
    - `models` integer: Distinct models below this one, at every level
    - `assets` integer: Distinct tickers the tree ultimately holds (cash excluded)
  - `as_of` string, date, nullable: Last market session covered by the results
  - `auto_update` boolean: Whether the nightly refresh is on
  - `refresh` ModelRefresh: Present freshness, independent of the last run's historical outcome.
    - `state` 'current' | 'disabled' | 'pending' | 'running' | 'waiting' | 'retrying' | 'blocked', required
    - `requested_session` string, date, nullable
    - `next_retry` string, date-time, nullable
    - `blockers` ModelRefreshBlocker[]
      - `model_id` string, required
      - `name` string, required
      - `reason_code` string, required
      - `reason` string, required
      - `run_id` string, nullable
  - `is_public` boolean, required
  - `is_favorite` boolean, nullable: Owner's favorite state; null for non-owner readers
  - `labels` string[], nullable: Owner's private organizational labels; null for non-owner readers
  - `url` string, nullable: Tear sheet URL; set once the model has built
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `description` string, nullable
  - `approved_revision_id` string, nullable
  - `editing_available` boolean
  - `prompt` string, required
  - `universe` string[], nullable: Symbols the model's code actually trades, as recorded by the runtime: tickers, member model IDs, or both. Null until a run has succeeded.
  - `components` ModelRef[]: Models this model holds directly
    - `id` string, required
    - `name` string, nullable
    - `symbol` string, nullable
    - `depth` integer: That model's own depth (0 = assets only)
  - `held_by` ModelRef[]: Models that hold this model directly. It cannot be deleted while any remain.
    - `id` string, required
    - `name` string, nullable
    - `symbol` string, nullable
    - `depth` integer: That model's own depth (0 = assets only)
  - `error` ModelError: Why the build failed. Present only when `status` is failed.
    - `type` string, nullable
    - `message` string, required
    - `code_excerpt` string, nullable: The lines of generated code around the failure, if any
    - `validation` ValidationError[], nullable: The rejection(s), present when the build failed validation
      - `type` string, required: Which rule rejected it: syntax, forbidden, price_source, nondeterministic, constants, entry_point, imports, inputs, members, universe, sources, metadata or other
      - `message` string, required: The rejection, written to teach the fix
      - `line` integer, nullable: The line named by the message, if any
  - `script_url` string, nullable: Download URL for the standalone Python implementation (runtime harness inlined, served as text/x-python). Null until code exists.
  - `window` ModelWindow: The span of history a model is judged over, and why it starts there. `start` and `end` bound the default view: every history endpoint applies them when no window is requested. `full_start` is the first computed bar; it precedes `start` only when the rule hides a partial-universe period, which `full_history=true` reveals.
    - `start` string, nullable: Default view start (YYYY-MM-DD)
    - `end` string, nullable: Last computed bar (YYYY-MM-DD)
    - `rule` 'two_members' | 'all_members' | 'first_member': Where the default view begins when no start_date is set. two_members (default): the first day two universe members have data, the earliest a rebalance between them means anything. all_members: the first day every member has data. first_member: the first day any member has data, the full history.
    - `start_date` string, nullable: View start set on the model, or null when the rule decides
    - `full_start` string, nullable: First computed bar; equals `start` when nothing is hidden
    - `constrained_by` string[]: Members whose inception set `start` under the rule; empty for an explicit date
  - `start_date` string, date, nullable: Where the default view of the history begins (YYYY-MM-DD). The full history is always computed and `full_history=true` on any history read reveals it; omission lets start_rule choose. The backtest's start date is an execution input, separate from this view window.
  - `start_rule` 'two_members' | 'all_members' | 'first_member': Where the default view begins when no start_date is set. two_members (default): the first day two universe members have data, the earliest a rebalance between them means anything. all_members: the first day every member has data. first_member: the first day any member has data, the full history.
  - `availability` ModelAvailability: Data availability recorded by the run: raw facts, not settings.
    - `partial` string, nullable: First computed bar (some members may still be missing)
    - `complete` string, nullable: First bar on which every universe member has data
    - `members` object, nullable: First bar with data for each universe member, {symbol: date}
    - `members_last` object, nullable: Last bar with data for each universe member, {symbol: date}, as the run saw it. A member behind the others lagged the final bar or has ended; the latest target was decided without it.
    - `backfills` object, nullable: History extensions the run applied, {symbol: source}. Present when a holding's series was extended before its own inception.
  - `schedule` ModelSchedule: Nightly auto-update state. Null until the model has succeeded once.
    - `enabled` boolean, required
    - `notify_email` boolean, required
    - `next_run_at` string, date-time, nullable
    - `last_run_at` string, date-time, nullable
    - `last_outcome` 'updated' | 'unchanged' | 'skipped' | 'failed', nullable: updated: new session folded in; unchanged: no new session yet; skipped/failed: the run did not complete; automatic-update preferences are unchanged
    - `last_error` string, nullable
    - `last_notified_at` string, date-time, nullable
  - `usage` ModelUsage: Billing usage for the most recent generation.
    - `units` integer, required
    - `base` integer, nullable
    - `tokens` integer, nullable
    - `seconds` integer, nullable
    - `effort` 'min' | 'mid' | 'max', nullable: The effort the build was billed at
  - `metadata` ModelMetadata: Run metadata computed by the runtime. Extra keys are passed through.
    - `universe` string[], nullable
    - `member_sources` object, nullable: Resolved member model/run identities and script hashes used by this result, including nested sources.
    - `start_date` string, nullable
    - `end_date` string, nullable
    - `initial_cash` number, nullable
    - `final_value` number, nullable
    - `trades_total` integer, nullable
    - `rebalance_dates` integer, nullable
    - `rebalances_per_year` number, nullable
    - `annual_turnover` number, nullable
    - `max_gross_exposure` number, nullable
    - `harness_version` string, nullable
    - `backfills` object[], nullable
    - `optimizers` unknown
    - `trade_log_truncated` boolean, nullable
    - `target_history_truncated` boolean, nullable
  - `custom_keys` ModelCustomKeys: Names recorded in a model's custom diagnostics, grouped by shape.
    - `series` string[]: Keys under `series`
    - `values` string[]: Keys under `values`
  - `inputs_schema` object, nullable: JSON Schema for `inputs` on a run, with defaults: the script's declared inputs followed by the platform's `start_date` (format date, default null). A run at the defaults computes the full history and goes live; a run with a `start_date` trades nothing before it and is a snapshot.
  - `live_run_id` string, nullable: The default run whose result is the live history
  - `estimate_cents` integer, nullable: On the 202 from create and rebuild: what the queued build holds against the balance, in cents. The charge that lands when it finishes replaces this figure. Null on every other read.
  - `build_id` string, nullable: The build that produced the current script; on a failed program, the failed build, so getBuild shows what was billed. getBuild returns it.
  - `is_owner` boolean: True when the caller owns this model

## Other responses

- `4XX`: The request was refused; `error.type` says why
- `5XX`: The server failed; quote `X-Request-Id` when reporting it

---

[API](https://skmtc.dev/ensemble/apis/ensemble-api.md) · [All operations](https://skmtc.dev/ensemble/apis/ensemble-api/llms.txt) · [OpenAPI document](https://skmtc.dev/ensemble/apis/ensemble-api/revisions/4c0fbd80c197?raw)
