> ## Documentation Index
> Fetch the complete documentation index at: https://docs.noonum.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Objective versioning

> How a strategy's draft becomes immutable versions, where run results live, and how to list and poll them.

## Overview

A strategy's **draft** is its current `objective` plus its `exclusions`. Each time you submit a draft that has changed, Noonum freezes it into an immutable **version** and promotes that version to **active**. Run results belong to a `(version, as-of date)` cell, so the same version can hold a live run and several historical runs side by side.

You rarely need version IDs for the basic loop. The defaults always read the active version's latest completed run. Versions matter when you want the full history of an objective or want to pin a read to an exact version and date.

## Draft, version, active

Three fields on the strategy object track this lifecycle.

* `active_version_id`: the last submitted version, and the one that serves results. It is `null` until you submit for the first time.
* `draft_version_id`: the saved version whose content matches your *current* draft. It is `null` when you have edited `objective` or `exclusions` since the last submit, which means you have unsaved changes.

<Note>
  Editing `objective` or `exclusions` with `PATCH /strategies/{strategyId}` changes the draft and sets `draft_version_id` to `null`. The next submit creates a new version, promotes it to active, and points `draft_version_id` back at it.
</Note>

A submit only creates a new version when the draft has changed. Re-submitting an unchanged draft runs the existing active version again, for example to refresh a live run or add a new historical date.

## Where run state lives

Run state is a property of a version and an as-of date, not of the strategy as a whole.

The strategy's top-level `status` and `completed` are a convenience rollup of the **active version's latest live run**. This is why polling the strategy object works the same as it did in v1: while a fresh submit is processing, the strategy's `status` climbs to `100`.

Per-version and per-date detail lives on the version object. Read it when you need the state of a specific historical run, or the full run count for a version.

## List versions

`GET /strategies/{strategyId}/versions` returns a strategy's versions, newest first. As the owner you see every version; a non-owner of a public strategy sees only the active one.

```bash theme={null}
curl -X GET "https://api.noonum.ai/v2/strategies/{strategyId}/versions" \
     -H "Authorization: Bearer YOUR_API_KEY_HERE"
```

Each item carries the version's `objective` and `exclusions` snapshot, its `is_active` flag, and its latest rollup run state, including `latest_run_date` and `runs_count`.

## Poll one version

`GET /strategies/{strategyId}/versions/{versionId}` is the per-version polling surface. It reports in one of two modes.

* **Rollup mode** (no `asOfDate`): the status of the version's most recent run, plus `latest_run_date` and `runs_count`.
* **Date-scoped mode** (`asOfDate` supplied): the state of that version's run on the given date. The rollup-only fields are `null`, and the call returns `404` if there is no run on that date.

```bash theme={null}
# Rollup: the version's most recent run
curl -X GET "https://api.noonum.ai/v2/strategies/{strategyId}/versions/{versionId}" \
     -H "Authorization: Bearer YOUR_API_KEY_HERE"

# Date-scoped: one (version, date) cell
curl -X GET "https://api.noonum.ai/v2/strategies/{strategyId}/versions/{versionId}?asOfDate=2025-06-30" \
     -H "Authorization: Bearer YOUR_API_KEY_HERE"
```

## Status codes

`status` reports a run's progress with the same code on both the strategy rollup and the version object.

| Code     | Meaning                                           |
| -------- | ------------------------------------------------- |
| `0`      | Not started, or the strategy was never submitted. |
| `1`–`95` | In progress.                                      |
| `100`    | Done. Results are ready to read.                  |
| `-1`     | Error.                                            |
| `-2`     | Permanently failed.                               |

<Tip>
  Treat `100` as success and stop polling. Treat `-1` and `-2` as terminal failures.
</Tip>

## Next step

See [Iterate and refine a strategy](/v2/guides/iterate-strategy) for the end-to-end loop of submitting, reviewing, excluding, and re-submitting across versions.
