> ## 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.

# Publish Disposition

> Publish a disposition draft as an immutable version.

### Overview

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

Freezes the current draft into a new immutable version, points `publishedVersionId` at it, and sets `state` to `enabled` so the disposition runs on every new completed call. Publishing validates strictly: every value must pin a published judge or extractor version, and the definition must have at least one value. Call [Estimate Disposition Cost](/api-v2/post/agents-id-dispositions-disposition-id-estimates) first and pass its `id`; publish recomputes the estimate and refuses if anything moved. Undo with [Disable Disposition](/api-v2/post/agents-id-dispositions-disposition-id-disable).

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>

### Body Parameters

Unknown fields are rejected.

<ParamField body="expectedDraftRevision" type="integer" required>
  The draft revision you estimated, at least `1`. Returns `409 CONFLICT` if the live revision differs. On success the draft revision becomes `expectedDraftRevision + 1` and the draft is kept in sync with the published snapshot, so `hasUnpublishedChanges` reads `false`.
</ParamField>

<ParamField body="estimateId" type="string" required>
  The `id` returned by Estimate Disposition Cost for this exact draft revision. Publish recomputes the estimate against fresh dependency reads and returns `409 CONFLICT` if the id no longer matches.
</ParamField>

<ParamField body="acknowledgeEstimate" type="boolean">
  Must be exactly `true` when the estimate's `totalUsdPerCall.expected` is greater than `0.0000`; omitting it in that case returns `400 BAD_REQUEST` with the message `Acknowledge the estimated recurring cost before publishing`. Any value other than `true` is rejected as an invalid body. Optional when the expected cost is zero.
</ParamField>

### Response

<ResponseField name="data" type="object">
  The newly created version.

  <Expandable title="version object">
    <ResponseField name="id" type="string">
      Unique identifier for the version. It is now the disposition's `publishedVersionId`.
    </ResponseField>

    <ResponseField name="dispositionId" type="string">
      The disposition this version belongs to.
    </ResponseField>

    <ResponseField name="versionNumber" type="number">
      Sequential number, one higher than the previous version, or `1` for a first publish.
    </ResponseField>

    <ResponseField name="definition" type="object">
      The frozen definition this version executes. `structured_extraction` sources carry the server-written `frozen` copy of the extractor prompt, output schema, and inference configuration.
    </ResponseField>

    <ResponseField name="publishedAt" type="string">
      ISO 8601 timestamp of publication.
    </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": "6168a24b-1863-422b-bbec-ed6d38395c41",
      "dispositionId": "1b179d4d-8830-43bd-b095-632f23bc4c57",
      "versionNumber": 2,
      "definition": {
        "name": "Appointment outcome",
        "description": "Did the caller book an appointment?",
        "timing": "immediate",
        "values": [
          {
            "id": "03bcc986-0183-4449-b9a6-a98b914edb72",
            "key": "booked",
            "label": "Appointment booked",
            "schema": { "kind": "boolean" },
            "source": {
              "kind": "judge",
              "judgeId": "dee902eb-e05c-46d3-8a33-0347c3871c07",
              "judgeVersionId": "c2781909-2c00-46d5-a2dd-db020a0f1b1f",
              "execution": { "reasoningEffort": "auto", "inputSourceIds": ["transcript"] }
            }
          }
        ],
        "transformation": {
          "version": 1,
          "root": {
            "kind": "object",
            "fields": {
              "booked": { "kind": "value", "valueId": "03bcc986-0183-4449-b9a6-a98b914edb72" }
            }
          }
        },
        "postCallWebhook": { "mode": "emit_followup" }
      },
      "publishedAt": "2026-09-10T18:40:03.512Z"
    },
    "errors": null
  }
  ```

  ```json Definition Invalid theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "BAD_REQUEST",
        "message": "Definition failed validation",
        "ext": "{\"problems\":[{\"valueId\":null,\"message\":\"Publish requires at least one value\"}]}"
      }
    ]
  }
  ```

  ```json Estimate Not Acknowledged theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "BAD_REQUEST",
        "message": "Acknowledge the estimated recurring cost before publishing"
      }
    ]
  }
  ```

  ```json Estimate Changed theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "CONFLICT",
        "message": "Pricing estimate changed — review the latest estimate before publishing"
      }
    ]
  }
  ```

  ```json Revision Moved theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "CONFLICT",
        "message": "Draft revision moved (expected 3) — re-estimate and publish again"
      }
    ]
  }
  ```

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

***

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