# Estimate an improvement pass

POST

/v1/proposals/improve/estimate

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

What a pass this input would start is estimated to cost, before you start it. The body is the start body of `POST /v1/proposals/improve`, resolved and reach-checked the same way: an unknown or inactive `fromVersion` (or the version serving the scope) answers `404 agent-version-not-found`, and a test set or scope the pass’s project doesn’t reach answers `400 reference-out-of-scope`, exactly as `improve` would. `estimatedCostUsd` is `min(budget.maxCostUsd, the replay count times the version's mean cost over its recent completed runs)` — clamped to the budget cap — and is absent when the version has no cost history; `basis` gives the unclamped inputs: the replay count, and that mean when there is one. The estimate prices every replay at that one mean, so a candidate whose prompt or settings cost more or less per run isn’t captured, and the estimate leaves out a prompt pass’s one-off drafting of its templates — a pass can cost more than the estimate. Because `estimatedCostUsd` is clamped to `budget.maxCostUsd`, an estimate at the cap means the pass is expected to spend its whole budget; the pass checks its cost before each comparison, so the one already running can take it a little over, and it starts no more once the cost reaches `budget.maxCostUsd`. It changes nothing (no pass starts) and takes no Idempotency-Key. Needs `publish` on the agent, and `write` on the pass’s project when it isn’t the version’s. Without improvement passes in this runtime, `501 improve-unsupported`.

## Authorizations

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

## Request Bodyrequired

application/json

Start an improvement pass.

object

**agentId**

required

string

**fromVersion**

The version whose settings it tunes. Default: the one serving `scope`.

string

**projectId**

The project the pass works in: `suiteId` must be a test set it reaches, the version must reach it, and the pass’s eval runs run there. A `project` or `segment` scope must be in it. Default, as an improve schedule’s: the scope’s project, else (a `tenant` or `org` scope) the agent version’s. A project other than the version’s needs `write` there.

string format: uuid

**scope**

required

One of: discriminator: kind

- **object**

  The agent’s default for the whole tenant.

  object

  **kind**

  required

  string

  Allowed values: tenant

- **object**

  An org’s projects.

  object

  **kind**

  required

  string

  Allowed values: org

  **orgId**

  required

  string format: uuid

- **object**

  One project.

  object

  **kind**

  required

  string

  Allowed values: project

  **projectId**

  required

  string format: uuid

- **object**

  A segment path within a project: it covers every run whose path starts with it.

  object

  **kind**

  required

  string

  Allowed values: segment

  **projectId**

  required

  string format: uuid

  **path**

  required

  Array\<object>

  \>= 1 items <= 8 items

  object

  **key**

  required

  Lowercase, like an identifier: `company`, `contact-role`.

  string

  /^\[a-z]\[a-z0-9\_-]{0,63}$/

  **value**

  required

  string

  \>= 1 characters <= 256 characters

**suiteId**

required

The test set (a judged eval suite). The pass splits it into a search part and a hold-out part, and proves its best candidate on the hold-out part.

string

**tiers**

`['settings']`: values for the tunable settings keys. `['prompt']`: a model drafts templates for the prompt block (needs `model`); a template that reads or names anything the agent doesn’t have is refused, and a drafted proposal always waits for a reviewer.

Array\<string>

default: settings >= 1 items <= 1 items

Allowed values: settings prompt

**model**

For a prompt pass: the tenant’s provider and model that drafts the templates.

object

**providerId**

required

string

**model**

required

string

**candidates**

For a prompt pass: how many templates it drafts.

integer

default: 3 >= 1 <= 5

**classWeights**

Which judgments the pass learns from. Omit it for the default: everyone’s (`as-recorded`) until the tenant, the project the pass reads its judgments from (its test set’s project, which can differ from where the agent is made), or the agent improved in that project has a restricted judge class, then only judgments recorded under one (`restricted-only`).

string

Allowed values: as-recorded restricted-only

**objective**

string

default: weightedYesShare

Allowed values: weightedYesShare weightedPrecisionAtK

**budget**

Default: $5 and 30 candidates.

object

**maxCostUsd**

number

\> 0 <= 100

**maxCandidates**

integer

\>= 1 <= 200

## Responses

### 200

The estimated cost.

application/json

What a pass this input would start is estimated to cost: the budget cap it’s clamped to, and — when the version has cost history — the estimate itself.

object

**estimatedCostUsd**

The estimate (US dollars): `basis.replays` times `basis.meanRunCostUsd`, or `maxCostUsd` when that’s smaller. Absent when the version has no cost history.

string

**maxCostUsd**

required

The budget cap the estimate is clamped to (`budget.maxCostUsd`, US dollars).

string

**basis**

required

What the estimate is built from.

object

**replays**

required

How many replay runs the pass’s comparisons would make.

integer

**meanRunCostUsd**

The version’s mean cost over its recent completed runs (US dollars). Absent with no cost history.

string

##### Examplegenerated

```json
{
  "estimatedCostUsd": "example",
  "maxCostUsd": "example",
  "basis": {
    "replays": 1,
    "meanRunCostUsd": "example"
  }
}
```

### 400

Malformed request body (`bad-input`), or a project or segment scope that isn’t in `projectId`. Or `reference-out-of-scope`: a project or segment scope doesn’t reach the agent, the version doesn’t reach the pass’s project (`/fromVersion`), or the test set isn’t one that project reaches (`details.issues`).

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

`fromVersion` (or the version serving the scope) is not an active version (`agent-version-not-found`); or the body’s `projectId` names no project of this tenant (`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"
  }
}
```

### 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"
  }
}
```

### 501

`improve-unsupported`: this runtime runs no improvement passes.

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

- [`POST /v1/proposals/improve`: Start an improvement pass](https://docs.kindgi.com/v0.3.0/reference/api/operations/proposalsimprove.md)
- [Error code `agent-version-not-found`](https://docs.kindgi.com/v0.3.0/reference/errors.md#agent-version-not-found)
- [Error code `bad-input`](https://docs.kindgi.com/v0.3.0/reference/errors.md#bad-input)
- [Error code `improve-unsupported`](https://docs.kindgi.com/v0.3.0/reference/errors.md#improve-unsupported)
- [Error code `project-not-found`](https://docs.kindgi.com/v0.3.0/reference/errors.md#project-not-found)
- [Error code `reference-out-of-scope`](https://docs.kindgi.com/v0.3.0/reference/errors.md#reference-out-of-scope)
- [Error code `request-too-large`](https://docs.kindgi.com/v0.3.0/reference/errors.md#request-too-large)
- [Every error code](https://docs.kindgi.com/v0.3.0/reference/errors.md)
