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

# Correct Test Run Value

> Record a corrected value for one call in a test run.

### Overview

<Note>
  Dispositions are enabled per organization. If your organization does not have access, these endpoints return `404`.
</Note>

Saves what the correct result should have been for one value on one call of a finished test run. Corrections are append-only: the engine's original result is never modified, and each call to this endpoint adds a new `revision` for that call and value. The run must be in a terminal status (`complete`, `partial`, or `failed`). Corrections show up on [Get Test Run Rows](/api-v2/get/agents-id-dispositions-disposition-id-runs-run-id-rows), in the CSV export, and feed [Align Disposition Test Run](/api-v2/post/agents-id-dispositions-disposition-id-runs-run-id-align). An organization may submit at most 300 corrections per hour.

Requires an admin, owner, operator, or prompter role.

### Headers

<ParamField header="authorization" type="string" required>
  Your API key for authentication.
</ParamField>

### Path Parameters

<ParamField path="agent_id" type="string" required>
  The agent's unique identifier. Must be a UUID; otherwise returns `400` with the message `agentId must be a valid UUID`. Returns `404 Agent not found` if the agent is not in your organization.
</ParamField>

<ParamField path="disposition_id" type="string" required>
  The disposition's unique identifier. Must be a UUID; otherwise returns `400` with the message `dispositionId must be a valid UUID`. Returns `404 Disposition not found` if it does not belong to this agent.
</ParamField>

<ParamField path="run_id" type="string" required>
  The test run's unique identifier. Must be a UUID; otherwise returns `400` with the message `runId must be a valid UUID`. Returns `404 Test run not found` if it does not belong to this disposition, and `409 CONFLICT` with the message `Corrections require a terminal test run` if the run is still `queued` or `running`, or was `cancelled`.
</ParamField>

<ParamField path="call_id" type="string" required>
  The call whose result you are correcting. Must be a UUID; otherwise returns `400` with the message `callId must be a valid UUID`. Returns `404` with the message `Test run case not found` if the call is not part of this run.
</ParamField>

<ParamField path="value_id" type="string" required>
  The definition value you are correcting. Must be a UUID; otherwise returns `400` with the message `valueId must be a valid UUID`. Returns `404` with the message `Disposition value not found in this run` if the run's definition snapshot has no such value, or `Run result not found for this value` if the call produced no result for it.
</ParamField>

### Body Parameters

Unknown fields are rejected with `400 BAD_REQUEST` and the message `Invalid request body`.

<ParamField body="state" type="string" required>
  `produced` when you are supplying the right value, or `no_value` when the call genuinely offers no answer for this value.
</ParamField>

<ParamField body="value" type="any">
  Required when `state` is `produced`; must be omitted when `state` is `no_value`. Must match the value's frozen `schema` exactly (a boolean for `boolean`, one of the option keys for `enum`, and so on), otherwise `400` with a message such as `Corrected value does not match the frozen boolean schema`. A string may be at most 4000 characters; an array or object may serialize to at most 16000 characters.
</ParamField>

<ParamField body="explanation" type="string" required>
  Why the engine's result was wrong, 40 to 4000 characters after trimming. Stored verbatim and used as training context by Align Disposition Test Run.
</ParamField>

### Response

Returns `201` on success.

<ResponseField name="data" type="object">
  The new correction revision.

  <Expandable title="correction object">
    <ResponseField name="id" type="string">
      Unique identifier for this revision.
    </ResponseField>

    <ResponseField name="testRunId" type="string">
      The test run.
    </ResponseField>

    <ResponseField name="testRunCaseId" type="string">
      Identifier of this call's execution within the run. Matches the `run_id` column of the CSV export.
    </ResponseField>

    <ResponseField name="callId" type="string">
      The call.
    </ResponseField>

    <ResponseField name="valueId" type="string">
      The definition value.
    </ResponseField>

    <ResponseField name="revision" type="number">
      `1` for the first correction of this call and value, incrementing with each further correction.
    </ResponseField>

    <ResponseField name="originalResult" type="object">
      The engine's result as it stood when you corrected it: `valueId`, `state`, and, when present, `value`, `error`, `rationale`, `evidence`, and `executedVia`, in the same shape as `results[]` on Get Test Run Rows.
    </ResponseField>

    <ResponseField name="correctedResult" type="object">
      `{ "valueId", "state" }` plus `value` when `state` is `produced`.
    </ResponseField>

    <ResponseField name="explanation" type="string">
      The trimmed explanation you supplied.
    </ResponseField>

    <ResponseField name="createdBy" type="string | null">
      ID of the user who saved the correction, or `null` when saved with an org-level key.
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO 8601 timestamp of the correction.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="errors" type="null | array">
  `null` on success, or a list of error objects if the request failed.
</ResponseField>

<ResponseExample>
  ```json Response theme={null}
  {
    "data": {
      "id": "1104a27d-55ca-4598-81bf-816ff21370b1",
      "testRunId": "9657e390-255f-4206-9bed-a05275cd0b94",
      "testRunCaseId": "c6fcc42a-f731-4521-b489-c0fd7e3ddfc9",
      "callId": "b9f0ebae-9698-4bd0-a86a-b4d031bf9e30",
      "valueId": "4a3d3d0e-4c73-4621-92a1-425676ccdb69",
      "revision": 1,
      "originalResult": {
        "valueId": "4a3d3d0e-4c73-4621-92a1-425676ccdb69",
        "state": "produced",
        "value": false,
        "rationale": "No appointment time was agreed before the caller hung up.",
        "executedVia": { "lane": "sync", "priceMultiplier": 1 }
      },
      "correctedResult": {
        "valueId": "4a3d3d0e-4c73-4621-92a1-425676ccdb69",
        "state": "produced",
        "value": true
      },
      "explanation": "The caller agreed to the slot at the very end of the call, after the agent's recap.",
      "createdBy": "0e9a481a-2920-4eef-b971-a36d9bbec695",
      "createdAt": "2026-09-10T20:14:33.870Z"
    },
    "errors": null
  }
  ```

  ```json Invalid Correction theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "BAD_REQUEST",
        "message": "Corrected value does not match the frozen boolean schema"
      }
    ]
  }
  ```

  ```json Conflict theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "CONFLICT",
        "message": "Corrections require a terminal test run"
      }
    ]
  }
  ```

  ```json Rate Limited theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "TOO_MANY_REQUESTS",
        "message": "Too many disposition corrections submitted for this organization — please wait before submitting more."
      }
    ]
  }
  ```

  ```json Not Found theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "NOT_FOUND",
        "message": "Test run case not found"
      }
    ]
  }
  ```
</ResponseExample>

***

Docs for agents: [llms.txt](/llms.txt)
