# Start an Improve run

POST

/v1/improve-runs

```sh
curl --request POST \
  --url https://example.com/v1/improve-runs \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{ "agentId": "example", "projectId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "tiers": [ "settings" ], "model": { "providerId": "example", "model": "example" }, "candidates": 1, "groupWeights": "as-recorded", "objective": "passRate", "budget": { "maxCostUsd": 1, "maxCandidates": 1 } }'
```

Starts an Improve run for an agent in a project. From the version the project runs (pinned there, else its Latest), it looks for better wording (the prompt tier) or settings values (the settings tier) on the project’s test set, learning from the project’s open corrections sorted to improve, within the budget. Its best change is proven on every case of the test set, at the reference’s repetitions: when it passes more cases than that version and fails none that passed, it becomes a suggested change for a reviewer. It answers at once with the Improve run, `running`. Under `kindgi dev`, the run counts in its project (its corrections, its test set and its cost), and its suggested change is for the whole workspace (the `tenant` scope), which the pack’s files serve: pinning it writes its block into the pack’s files. The readiness check (`POST /v1/improve-runs/check`) runs first: when something the Improve run needs is missing, it’s refused with `409 improve-not-ready`, listing every missing item at once (`details.items`, each with its fix); while the agent has a running Improve run in the project, with `409 improve-run-running` (`details.improveRunId`). An Improve run going when its project is suspended ends `cancelled`, with the reason in `cancelReason`. Needs `publish` on the agent; for an agent more than one project serves, `write` where its versions are made. Without Improve runs in this runtime, `501 improve-unsupported`.

## Authorizations

- **[bearerAuth](https://docs.kindgi.com/v0.5.0/reference/api.md#bearerauth)**

## Parameters

### Header Parameters

**Idempotency-Key**

string

\>= 1 characters

Caller-supplied idempotency key, scoped to the caller: the same key from someone else in the workspace is their own request (from 0.1.5). Retries with the same key return the original response byte-identical (per `docs/API-ROUTE-CONVENTIONS.md` §3.1). A retry sent while the first request still runs is answered `409 idempotency-key-in-flight` with `Retry-After`, on a runtime whose store holds keys (from 0.1.5); retry after it, and you get the first request’s answer. An answer that carries a secret (a new API key or public run token, a session token, a generated signing secret) isn’t kept: a retry gets `409 idempotency-key-replay-withheld`, with the first request’s status and when it succeeded (from 0.1.5). A request whose key store can’t be read before it runs is answered `503 idempotency-store-unavailable` with `Retry-After`: nothing ran, so retry with the same key (from 0.3.0).

## Request Bodyrequired

application/json

Start an Improve run for an agent in a project, or check one first. It starts from the version the project runs, learns from the project’s corrections, and searches and proves on the project’s test set. A field not listed here is refused (`400 bad-input`, naming it).

object

**agentId**

required

string

**projectId**

required

The project the Improve run works in.

string format: uuid

**tiers**

What it tries: `prompt` (a model drafts new wording for the prompt block; a template that reads or names anything the agent doesn’t have is refused, and a drafted suggested change always waits for a reviewer) and `settings` (values for the settings Improve may tune). Omit it for every tier that’s ready.

Array\<string>

\>= 1 items <= 2 items unique items

Allowed values: settings prompt

**model**

For the prompt tier: the workspace’s provider and model that drafts the templates. Omit it for the model of the version’s own model-settings block.

object

**providerId**

required

string

**model**

required

string

**candidates**

For the prompt tier: how many templates it drafts. Omit it for the runtime’s default.

integer

\>= 1 <= 5

**groupWeights**

Which corrections the Improve run learns from. Omit it for the default: everyone’s (`as-recorded`) until the workspace, the project, or the agent in the project has an expert group, then only corrections recorded under one (`experts-only`).

string

Allowed values: as-recorded experts-only

**objective**

string

default: passRate

Allowed values: passRate weightedPrecisionAtK

**budget**

Default: $5 and 30 candidates.

object

**maxCostUsd**

number

\> 0 <= 100

**maxCandidates**

integer

\>= 1 <= 200

## Responses

### 202

The Improve run, running.

application/json

An Improve run: the runtime looking for better wording or settings values for an agent in a project, on the project’s test set, within a budget. A candidate that does better becomes a suggested change.

object

**id**

required

string format: uuid

**agentId**

required

string

**projectId**

The project it works in. Absent from older servers, and on a run started for a workspace or an org before Improve runs worked in a project.

string format: uuid

**startsFrom**

required

The version an Improve run starts from: the one the project runs, pinned there (`pin`) or the agent’s latest (`latest`).

object

**version**

required

string

**follows**

required

string

Allowed values: pin latest

**testSetVersion**

The version of the project’s test set it searches and proves on; absent until it’s frozen.

string

**setAside**

The test set’s cases set aside for the proof: `cases` of `of`. None with fewer than five. Absent from older servers.

object

**cases**

required

integer

**of**

required

integer

**tiers**

required

The tiers it tries, the prompt tier first.

Array\<string>

Allowed values: settings prompt

**objective**

required

string

Allowed values: passRate weightedPrecisionAtK

**groupWeights**

required

Which corrections its comparisons count.

string

Allowed values: as-recorded experts-only

**model**

For the prompt tier: the provider and model that drafts the templates.

object

**providerId**

required

string

**model**

required

string

**candidates**

For the prompt tier: how many templates it drafts.

integer

\>= 1 <= 5

**budget**

required

object

**maxCostUsd**

required

The most the Improve run’s comparisons may cost, in US dollars.

number

\> 0 <= 100

**maxCandidates**

required

The most candidates it compares.

integer

\>= 1 <= 200

**requestedBy**

required

`user:<id>` or `service:<id>`.

string

**status**

required

string

Allowed values: running completed failed cancelled

**tried**

required

Candidates tried so far.

integer

**costUsd**

required

What its comparisons have cost so far (US dollars).

string

**outcome**

One of: discriminator: kind

- **object**

  A change passed more cases than the version the run started from, and failed none that passed: the run wrote it as a suggested change for a reviewer to decide.

  object

  **kind**

  required

  string

  Allowed value: suggested

  **suggestedChangeId**

  required

  string format: uuid

- **object**

  No change the run tried did better: `reason` says why, and `holdOut` has the best change’s numbers when one got that far.

  object

  **kind**

  required

  string

  Allowed value: nothing-better

  **reason**

  required

  string

  **holdOut**

  The best change’s proof numbers, when one got that far: on every case, or on the set-aside part for a run stored before that.

  object

  **baseline**

  required

  number | null

  **candidate**

  required

  number | null

  **delta**

  required

  number | null

  **spread**

  number

- **object**

  The run reached its budget with nothing kept.

  object

  **kind**

  required

  string

  Allowed value: cost-cap

  **spentUsd**

  required

  What it spent, in US dollars.

  string

- **object**

  The run failed: `message` says why.

  object

  **kind**

  required

  string

  Allowed value: failed

  **message**

  required

  string

**takes**

The ids of the corrections it took when it started. Absent from older servers.

Array\<string>

**cancelReason**

Why a `cancelled` Improve run stopped when nobody cancelled it: a comparison’s test run was cancelled for it (that run’s `cancelReason`, e.g. `project-suspended`). It wrote no suggested change. Absent when it was cancelled.

string

**comparisons**

Its comparisons so far, each a test run to open: `reference` (the version as it is, on each part: what the proof is held to, case by case), each `candidate` (the block and the values it changed, on the search part: what picks the change to suggest), and the `proof` (the suggested change, on `all` the cases at the reference’s repetitions: what keeps it or not; an Improve run from before 0.4 ran its proof on the hold-out part). Absent from older servers.

Array\<object>

object

**testRunId**

string format: uuid

**role**

required

string

Allowed values: reference candidate proof

**part**

required

string

Allowed values: search hold-out all

**blockId**

string

**changed**

object

**_key_**

additional properties

any

**score**

number | null

**failed**

string

**refused**

For a drafted template that was never compared: why the check refused it (what it reads or names that the agent doesn’t have, or its size).

Array\<object>

object

**path**

required

string

**message**

required

string

**why**

For a drafted template: what the drafter meant it to change.

string

**trigger**

The improve schedule and fire that started it (`GET /v1/schedules/{triggerId}/fires`); absent for an Improve run a person started.

object

**triggerId**

required

string

**fireId**

required

string

**createdAt**

required

string format: date-time

**updatedAt**

required

string format: date-time

**finishedAt**

string format: date-time

##### Example

```json
{
  "startsFrom": {
    "follows": "pin"
  },
  "tiers": [
    "settings"
  ],
  "objective": "passRate",
  "groupWeights": "as-recorded",
  "status": "running",
  "outcome": {
    "kind": "suggested"
  },
  "comparisons": [
    {
      "role": "reference",
      "part": "search"
    }
  ]
}
```

### 400

Malformed request body (`bad-input`): no `projectId`, or a field the body doesn’t have (`scope`, `testSetId` and `fromVersion` among them), named in the message.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 401

Missing / malformed / expired / revoked bearer token.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 404

The body’s `projectId` names no project of this workspace (`project-not-found`).

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 409

`improve-not-ready`: something the Improve run needs is missing (`details.items`, as `POST /v1/improve-runs/check` lists them). `improve-run-running`: the agent has a running Improve run in the project (`details.improveRunId`); one runs at a time. Or `registry-read-only`: the agent registry is read-only and takes no versions an Improve run makes; the message says why. Or Idempotency-Key was reused with a different body.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 413

The request body is over the API’s limit (`request-too-large`; `details.maxBytes` says how much).

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 500

Server error (unmapped domain code or framework crash).

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 501

`improve-unsupported`: this runtime runs no Improve runs.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

### 503

The `Idempotency-Key` store couldn’t be read before the request ran (`idempotency-store-unavailable`), so nothing was changed; `Retry-After` (whole seconds) says when to try again with the same key.

application/json

object

**error**

required

object

**code**

required

Stable machine-readable discriminant. Values match domain error codes (see `docs/API-ROUTE-CONVENTIONS.md` §4.3).

string

**message**

required

string

**details**

Optional, kind-specific.

object

**_key_**

additional properties

any

**requestId**

required

Server-assigned request id; also echoed via `X-Request-Id` header.

string

##### Examplegenerated

```json
{
  "error": {
    "code": "example",
    "message": "example",
    "details": {},
    "requestId": "example"
  }
}
```

## See also

- [`GET /v1/improve-runs`: List Improve runs](https://docs.kindgi.com/v0.5.0/reference/api/operations/improverunslist.md)
- [Kindgi 0.4.0](https://docs.kindgi.com/v0.5.0/releases/0.4.0.md)
- [Error code `bad-input`](https://docs.kindgi.com/v0.5.0/reference/errors.md#bad-input)
- [Error code `idempotency-store-unavailable`](https://docs.kindgi.com/v0.5.0/reference/errors.md#idempotency-store-unavailable)
- [Error code `improve-not-ready`](https://docs.kindgi.com/v0.5.0/reference/errors.md#improve-not-ready)
- [Error code `improve-run-running`](https://docs.kindgi.com/v0.5.0/reference/errors.md#improve-run-running)
- [Error code `improve-unsupported`](https://docs.kindgi.com/v0.5.0/reference/errors.md#improve-unsupported)
- [Error code `project-not-found`](https://docs.kindgi.com/v0.5.0/reference/errors.md#project-not-found)
- [Error code `registry-read-only`](https://docs.kindgi.com/v0.5.0/reference/errors.md#registry-read-only)
- [Error code `request-too-large`](https://docs.kindgi.com/v0.5.0/reference/errors.md#request-too-large)
- [Every error code](https://docs.kindgi.com/v0.5.0/reference/errors.md)
