# Promote a deployment to the next environment

POST

/v1/deployments/{deploymentId}/promotions

```sh
curl --request POST \
  --url https://example.com/v1/deployments/example/promotions \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{ "toProjectId": "example", "reason": "example", "makeLive": true }'
```

Moves the exact build a deployment runs into the next environment of its environment order: a new deployment of the target project with the same image, signature, signer and contents, and `promotedFromDeploymentId`. Nothing is built again and no registry is written. The edits of the build’s agents and flows (versions made from a version it ships) move with it (`moved.agents[].carried`); edits made from a version it doesn’t ship stay (`leftBehind`). Needs `read` on the deployment’s project and `admin` on the target. Refused, with nothing written, when the target isn’t the next environment, the deployment (or the target’s copy) no longer serves, its signer is no longer trusted or its signature doesn’t verify, or a value the build needs isn’t ready in the target. The target having this build already answers `200` with its deployment, and records the edits made since.

## Authorizations

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

## Parameters

### Path Parameters

**deploymentId**

required

string

\>= 1 characters

The deployment to promote: one serving an environment of an order.

## Request Bodyrequired

application/json

object

**toProjectId**

required

The next environment of the deployment’s order.

string

\>= 1 characters

**reason**

Why, kept in the `deployment-promoted` audit record.

string

<= 1000 characters

**makeLive**

Make every agent version the promotion carries live in the target project, each through its scope’s gate. The answer’s `live` reports each. An error answered after some carried agents were already pinned lists those in `error.details.live`, in `live`’s shape.

boolean

##### Examplegenerated

```json
{
  "toProjectId": "example",
  "reason": "example",
  "makeLive": true
}
```

## Responses

### 200

The target has this build already: its deployment, with the edits made since recorded.

application/json

object

**deployment**

required

object

**deploymentId**

required

string

\>= 1 characters

**tenantId**

required

string format: uuid

**imageRef**

required

Full digest-pinned OCI reference: `<host>/<repo>@sha256:<hex>`.

string

**imageDigest**

required

Idempotency key. Extracted from `imageRef` after the `@`.

string

/^sha256:\[0-9a-f]{64}$/

**artifactVersion**

required

Issuer-supplied `YYYYMMDD.N` — matches what was signed.

string

/^\d{8}\\.\d+$/

**indexHash**

required

Sha256 of the canonicalised `/app/index.json` inside the image.

string

/^sha256:\[0-9a-f]{64}$/

**signerKeyId**

required

string

\>= 1 characters

**signerPublicKey**

required

Base64 of the raw Ed25519 public key bytes (32 bytes → 44 chars).

string

**signature**

required

Base64 of the raw Ed25519 signature (64 bytes → 88 chars).

string

**publishedAt**

required

Issuer-supplied timestamp inside the signed envelope.

string format: date-time

**activatedAt**

required

Server-side ledger timestamp — when the register call succeeded.

string format: date-time

**projectId**

The project the deploy named, which its primitives were registered into. Absent for a tenant-wide deploy (the tenant’s Default project).

string format: uuid

**packEnv**

The names the pack service reads from its process environment, as the image’s `index.json` declares them (`env`), each list in name order. Names only, never a value. On a deployment: absent when it declares none, and from older servers.

object

**required**

required

Names the pack service needs, set and non-empty, to be ready.

Array\<string>

**optional**

required

Names the pack reads when present.

Array\<string>

**promotedFromDeploymentId**

When this deployment was made by promoting another into the next environment of its order: the deployment it was promoted from. Absent for one deployed directly.

string

\>= 1 characters

**packId**

The pack’s id, from the image’s index. Absent from a runtime that doesn’t keep it.

string

**endpoint**

Its pack service’s status, when the server routes each pack call to the deployment that shipped the tool (`KINDGI_PACK_ROUTING=per-deployment`). Absent otherwise. `pending`: no pack service yet, and calls to its tools fail (`pack-endpoint-pending`) rather than go to another deployment. `ready`: calls go to its own pack service. `cleared`: its pack service was taken down, and calls fail (`pack-endpoint-cleared`); it carries `waiting` or `retired` to say whether it comes back. Carries no URL and no token.

object

**status**

required

string

Allowed values: pending ready cleared

**since**

required

When the status last changed.

string format: date-time

**problem**

While the deployment waits for a pack service (`pending`, or `cleared` and `waiting`): the last reason recorded while it waited. A `ready` endpoint has none, nor a `retired` one. A fixed code, never free text.

object

**code**

required

One of a fixed list; a later runtime may add codes, so treat an unknown one as a reason not yet named. The server refused the endpoint it was given: `endpoint-url-invalid` (not `https`, or with user info or a path), `endpoint-host-not-allowed` (the host isn’t on the operator’s allowlist), `endpoint-name-mismatch` (the host doesn’t name this deployment’s service), `endpoint-unreachable` (the pack service didn’t answer), `endpoint-info-mismatch` (it answered as another pack or version), `image-not-allowed` (the image is outside the tenant’s repository). The pack service couldn’t be created: `tenant-not-provisioned` (the tenant has nowhere to run pack services yet), `capacity-unavailable` (no room for another pack service just now), `service-start-failed` (the image was deployed but didn’t start). It can’t be given its declared environment (`GET /v1/deployments/{deploymentId}/pack-env` names the names): `pack-env-ambiguous`, `pack-env-secret-not-yet`, `pack-env-missing`, `pack-env-secret-unreadable` (a name’s secret can’t be read for a reason the platform fixes, not the owner; it’s tried again). It can’t be given its secrets: `pack-env-secrets-unaudited` (the runtime has nowhere to audit a secret it gives out; the platform fixes it, and it’s tried again), `pack-env-secret-too-large` (a secret’s value is over 32768 bytes, the most a pack service can be given), `pack-env-secret-capacity` (a name is set only as a secret, and there’s no room just now for a pack service that can be given one, apart from other projects’; it’s tried again).

string

**since**

required

When it was recorded.

string format: date-time

**waiting**

`cleared` only: a pack service is wanted for it again, as once a suspension that took its service down is lifted, and it lists as needing one; `problem` says why it isn’t back yet. A `cleared` endpoint carries this or `retired`, never both. Absent from older servers, which send neither.

boolean

**retired**

`cleared` only: why no pack service is wanted for it now. `superseded` is for good: newer deployments ship every tool version and check it does, so no new call reaches it; a tool call a step made on it still goes back to it when the step runs again, and fails closed (`pack-endpoint-cleared`). `tenant-closing`, `tenant-suspended`, `project-suspended` and `pack-suspended` last until the tenant, project or pack is restored. A later runtime may add reasons, so treat an unknown one as a reason not yet named. A `cleared` endpoint carries this or `waiting`, never both. Absent from older servers, which send neither.

string

**packEnvProblem**

`ready` only: the pack service runs on the values it was last given, because the newest can’t be given to it (a required one was removed, say, or a secret can’t be given), or didn’t start (`pack-env-update-failed`). Gone once they can, or do. For a name that can’t be given, `GET /v1/deployments/{deploymentId}/pack-env` names it. Absent from older servers.

object

**code**

required

Why a `ready` pack service runs on the values it was last given: a `PackEnvProblemCode`, so the newest can’t be given to it; `pack-env-update-failed`: they were given, and its new revision with them didn’t start, so the last ready one serves. That revision is tried again for an hour after it’s first recorded; setting the values again is a new revision, tried again too. The orchestrator couldn’t give it its secrets: `pack-env-secrets-unaudited` (the runtime has nowhere to audit a secret it gives out, so it gives none; the platform fixes it), `pack-env-secret-too-large` (a secret’s value is over 32768 bytes, the most a pack service can be given), `pack-env-secret-redeploy` (a name is now set only as a secret, and this pack service was made where no secret can be given to it; a new deployment’s can be, from a new build of the pack). A service held as `pack-env-secret-unreadable` or `pack-env-secrets-unaudited` is listed by `GET /v1/system/pack-env` every time, with its `held`, as the revision doesn’t move when the platform fixes it. A later runtime may add codes, so treat an unknown one as a reason not yet named.

string

Allowed values: pack-env-ambiguous pack-env-secret-not-yet pack-env-missing pack-env-secret-unreadable pack-env-update-failed pack-env-secrets-unaudited pack-env-secret-too-large pack-env-secret-redeploy

**since**

required

When it was recorded.

string format: date-time

**primitives**

required

object

**tools**

required

integer

**guardrails**

required

integer

**agents**

required

integer

**flows**

required

integer

**contents**

required

object

**tools**

required

Array\<object>

object

**id**

required

string

**version**

Absent for guardrails, which have no version.

string

**guardrails**

required

Array\<object>

object

**id**

required

string

**version**

Absent for guardrails, which have no version.

string

**agents**

required

Array\<object>

object

**id**

required

string

**version**

required

The version the agent is registered as.

string

**authoredVersion**

The version the agent’s or flow’s definition names, present when it differs from `version`: that version was registered already with other pins or content, and versions never change, so the deploy registered the next free version in its line (or an earlier deploy did).

string

**reason**

Why `version` differs from `authoredVersion`: `pins-changed` (a tool or agent it uses has a new version), `unpinned` (`authoredVersion` was published before pins existed), `version-taken` (`authoredVersion` is registered with other content).

string

Allowed values: pins-changed unpinned version-taken

**newVersion**

`true`: this deploy registered `version`; `false`: an earlier deploy did.

boolean

**pinChanges**

For `pins-changed`: the pins that differ from `authoredVersion`’s.

Array\<object>

One pin that differs between two versions of an agent or a flow.

object

**kind**

required

string

Allowed values: tool prompt setting agent

**id**

required

string

**from**

The earlier version’s pin; absent when it had none.

string

**to**

The later version’s pin; absent when it has none.

string

**flows**

required

Array\<object>

object

**id**

required

string

**version**

required

The version the agent is registered as.

string

**authoredVersion**

The version the agent’s or flow’s definition names, present when it differs from `version`: that version was registered already with other pins or content, and versions never change, so the deploy registered the next free version in its line (or an earlier deploy did).

string

**reason**

Why `version` differs from `authoredVersion`: `pins-changed` (a tool or agent it uses has a new version), `unpinned` (`authoredVersion` was published before pins existed), `version-taken` (`authoredVersion` is registered with other content).

string

Allowed values: pins-changed unpinned version-taken

**newVersion**

`true`: this deploy registered `version`; `false`: an earlier deploy did.

boolean

**pinChanges**

For `pins-changed`: the pins that differ from `authoredVersion`’s.

Array\<object>

One pin that differs between two versions of an agent or a flow.

object

**kind**

required

string

Allowed values: tool prompt setting agent

**id**

required

string

**from**

The earlier version’s pin; absent when it had none.

string

**to**

The later version’s pin; absent when it has none.

string

**created**

required

`true`: the promotion made this deployment (`201`). `false`: the target had this build already (`200`), and only the versions it lacked were carried.

boolean

**moved**

required

object

**packId**

string

**imageDigest**

required

string

/^sha256:\[0-9a-f]{64}$/

**agents**

required

Array\<object>

object

**id**

required

string

**version**

string

**carried**

Carried with the build: an edit of a version it ships. Absent for one it ships.

boolean

**flows**

required

Array\<object>

object

**id**

required

string

**version**

string

**carried**

Carried with the build: an edit of a version it ships. Absent for one it ships.

boolean

**tools**

required

Array\<object>

object

**id**

required

string

**version**

Absent for guardrails, which have no version.

string

**guardrails**

required

Array\<object>

object

**id**

required

string

**version**

Absent for guardrails, which have no version.

string

**leftBehind**

Edits of the build’s agents and flows that stay behind; absent when none.

Array\<object>

object

**kind**

required

`agent` or `flow`; a later runtime may add kinds, so treat an unknown one as an item not yet named.

string

**id**

required

string

**version**

required

string

**from**

required

The version its chain of edits starts from.

string

**live**

Each carried agent pinned live in the target; present only when `makeLive` was asked.

Array\<object>

object

**id**

required

string

**version**

required

string

**pinned**

required

Live now (`true`), or waiting on a gate — an approval, or a check it failed (`false`, with `gate`).

boolean

**gate**

object

**status**

required

string

Allowed values: promoted pending-approval refused superseded rejected expired

**promotionId**

required

string format: uuid

**policy**

One of:

- **object**

  object

  **id**

  required

  string

  **version**

  required

  string

- **null**

  null

**approvalId**

The approval a `pending-approval` pin waits on.

string

**checks**

Array\<object>

One of a gate’s checks, as the promotion records it.

object

**name**

required

Stable: `comparison.required`, `comparison.status`, `comparison.freshness`, `comparison.suite`, `sameContents`, `baselineIsLive`, `scopeCovered`, `evidence.<metric>.minCases|minWeight|baselineMinCases|baselineMinWeight`, `metric.<metric>.k|minCandidate|maxDrop`, `replay.maxDiverged|maxErrors|maxRefusedWrites|maxStopped`, `classWeights.restrictedOnly`.

string

**passed**

required

boolean

**message**

required

A plain sentence: what was found against what the policy asks.

string

**value**

number | string

**threshold**

number | string

##### Example

```json
{
  "deployment": {
    "endpoint": {
      "status": "pending",
      "waiting": true,
      "packEnvProblem": {
        "code": "pack-env-ambiguous"
      }
    },
    "contents": {
      "agents": [
        {
          "reason": "pins-changed",
          "pinChanges": [
            {
              "kind": "tool"
            }
          ]
        }
      ],
      "flows": [
        {
          "reason": "pins-changed",
          "pinChanges": [
            {
              "kind": "tool"
            }
          ]
        }
      ]
    }
  },
  "moved": {
    "agents": [
      {
        "carried": true
      }
    ],
    "flows": [
      {
        "carried": true
      }
    ]
  },
  "live": [
    {
      "gate": {
        "status": "promoted"
      }
    }
  ]
}
```

### 201

Promoted: a new deployment in the target.

application/json

object

**deployment**

required

object

**deploymentId**

required

string

\>= 1 characters

**tenantId**

required

string format: uuid

**imageRef**

required

Full digest-pinned OCI reference: `<host>/<repo>@sha256:<hex>`.

string

**imageDigest**

required

Idempotency key. Extracted from `imageRef` after the `@`.

string

/^sha256:\[0-9a-f]{64}$/

**artifactVersion**

required

Issuer-supplied `YYYYMMDD.N` — matches what was signed.

string

/^\d{8}\\.\d+$/

**indexHash**

required

Sha256 of the canonicalised `/app/index.json` inside the image.

string

/^sha256:\[0-9a-f]{64}$/

**signerKeyId**

required

string

\>= 1 characters

**signerPublicKey**

required

Base64 of the raw Ed25519 public key bytes (32 bytes → 44 chars).

string

**signature**

required

Base64 of the raw Ed25519 signature (64 bytes → 88 chars).

string

**publishedAt**

required

Issuer-supplied timestamp inside the signed envelope.

string format: date-time

**activatedAt**

required

Server-side ledger timestamp — when the register call succeeded.

string format: date-time

**projectId**

The project the deploy named, which its primitives were registered into. Absent for a tenant-wide deploy (the tenant’s Default project).

string format: uuid

**packEnv**

The names the pack service reads from its process environment, as the image’s `index.json` declares them (`env`), each list in name order. Names only, never a value. On a deployment: absent when it declares none, and from older servers.

object

**required**

required

Names the pack service needs, set and non-empty, to be ready.

Array\<string>

**optional**

required

Names the pack reads when present.

Array\<string>

**promotedFromDeploymentId**

When this deployment was made by promoting another into the next environment of its order: the deployment it was promoted from. Absent for one deployed directly.

string

\>= 1 characters

**packId**

The pack’s id, from the image’s index. Absent from a runtime that doesn’t keep it.

string

**endpoint**

Its pack service’s status, when the server routes each pack call to the deployment that shipped the tool (`KINDGI_PACK_ROUTING=per-deployment`). Absent otherwise. `pending`: no pack service yet, and calls to its tools fail (`pack-endpoint-pending`) rather than go to another deployment. `ready`: calls go to its own pack service. `cleared`: its pack service was taken down, and calls fail (`pack-endpoint-cleared`); it carries `waiting` or `retired` to say whether it comes back. Carries no URL and no token.

object

**status**

required

string

Allowed values: pending ready cleared

**since**

required

When the status last changed.

string format: date-time

**problem**

While the deployment waits for a pack service (`pending`, or `cleared` and `waiting`): the last reason recorded while it waited. A `ready` endpoint has none, nor a `retired` one. A fixed code, never free text.

object

**code**

required

One of a fixed list; a later runtime may add codes, so treat an unknown one as a reason not yet named. The server refused the endpoint it was given: `endpoint-url-invalid` (not `https`, or with user info or a path), `endpoint-host-not-allowed` (the host isn’t on the operator’s allowlist), `endpoint-name-mismatch` (the host doesn’t name this deployment’s service), `endpoint-unreachable` (the pack service didn’t answer), `endpoint-info-mismatch` (it answered as another pack or version), `image-not-allowed` (the image is outside the tenant’s repository). The pack service couldn’t be created: `tenant-not-provisioned` (the tenant has nowhere to run pack services yet), `capacity-unavailable` (no room for another pack service just now), `service-start-failed` (the image was deployed but didn’t start). It can’t be given its declared environment (`GET /v1/deployments/{deploymentId}/pack-env` names the names): `pack-env-ambiguous`, `pack-env-secret-not-yet`, `pack-env-missing`, `pack-env-secret-unreadable` (a name’s secret can’t be read for a reason the platform fixes, not the owner; it’s tried again). It can’t be given its secrets: `pack-env-secrets-unaudited` (the runtime has nowhere to audit a secret it gives out; the platform fixes it, and it’s tried again), `pack-env-secret-too-large` (a secret’s value is over 32768 bytes, the most a pack service can be given), `pack-env-secret-capacity` (a name is set only as a secret, and there’s no room just now for a pack service that can be given one, apart from other projects’; it’s tried again).

string

**since**

required

When it was recorded.

string format: date-time

**waiting**

`cleared` only: a pack service is wanted for it again, as once a suspension that took its service down is lifted, and it lists as needing one; `problem` says why it isn’t back yet. A `cleared` endpoint carries this or `retired`, never both. Absent from older servers, which send neither.

boolean

**retired**

`cleared` only: why no pack service is wanted for it now. `superseded` is for good: newer deployments ship every tool version and check it does, so no new call reaches it; a tool call a step made on it still goes back to it when the step runs again, and fails closed (`pack-endpoint-cleared`). `tenant-closing`, `tenant-suspended`, `project-suspended` and `pack-suspended` last until the tenant, project or pack is restored. A later runtime may add reasons, so treat an unknown one as a reason not yet named. A `cleared` endpoint carries this or `waiting`, never both. Absent from older servers, which send neither.

string

**packEnvProblem**

`ready` only: the pack service runs on the values it was last given, because the newest can’t be given to it (a required one was removed, say, or a secret can’t be given), or didn’t start (`pack-env-update-failed`). Gone once they can, or do. For a name that can’t be given, `GET /v1/deployments/{deploymentId}/pack-env` names it. Absent from older servers.

object

**code**

required

Why a `ready` pack service runs on the values it was last given: a `PackEnvProblemCode`, so the newest can’t be given to it; `pack-env-update-failed`: they were given, and its new revision with them didn’t start, so the last ready one serves. That revision is tried again for an hour after it’s first recorded; setting the values again is a new revision, tried again too. The orchestrator couldn’t give it its secrets: `pack-env-secrets-unaudited` (the runtime has nowhere to audit a secret it gives out, so it gives none; the platform fixes it), `pack-env-secret-too-large` (a secret’s value is over 32768 bytes, the most a pack service can be given), `pack-env-secret-redeploy` (a name is now set only as a secret, and this pack service was made where no secret can be given to it; a new deployment’s can be, from a new build of the pack). A service held as `pack-env-secret-unreadable` or `pack-env-secrets-unaudited` is listed by `GET /v1/system/pack-env` every time, with its `held`, as the revision doesn’t move when the platform fixes it. A later runtime may add codes, so treat an unknown one as a reason not yet named.

string

Allowed values: pack-env-ambiguous pack-env-secret-not-yet pack-env-missing pack-env-secret-unreadable pack-env-update-failed pack-env-secrets-unaudited pack-env-secret-too-large pack-env-secret-redeploy

**since**

required

When it was recorded.

string format: date-time

**primitives**

required

object

**tools**

required

integer

**guardrails**

required

integer

**agents**

required

integer

**flows**

required

integer

**contents**

required

object

**tools**

required

Array\<object>

object

**id**

required

string

**version**

Absent for guardrails, which have no version.

string

**guardrails**

required

Array\<object>

object

**id**

required

string

**version**

Absent for guardrails, which have no version.

string

**agents**

required

Array\<object>

object

**id**

required

string

**version**

required

The version the agent is registered as.

string

**authoredVersion**

The version the agent’s or flow’s definition names, present when it differs from `version`: that version was registered already with other pins or content, and versions never change, so the deploy registered the next free version in its line (or an earlier deploy did).

string

**reason**

Why `version` differs from `authoredVersion`: `pins-changed` (a tool or agent it uses has a new version), `unpinned` (`authoredVersion` was published before pins existed), `version-taken` (`authoredVersion` is registered with other content).

string

Allowed values: pins-changed unpinned version-taken

**newVersion**

`true`: this deploy registered `version`; `false`: an earlier deploy did.

boolean

**pinChanges**

For `pins-changed`: the pins that differ from `authoredVersion`’s.

Array\<object>

One pin that differs between two versions of an agent or a flow.

object

**kind**

required

string

Allowed values: tool prompt setting agent

**id**

required

string

**from**

The earlier version’s pin; absent when it had none.

string

**to**

The later version’s pin; absent when it has none.

string

**flows**

required

Array\<object>

object

**id**

required

string

**version**

required

The version the agent is registered as.

string

**authoredVersion**

The version the agent’s or flow’s definition names, present when it differs from `version`: that version was registered already with other pins or content, and versions never change, so the deploy registered the next free version in its line (or an earlier deploy did).

string

**reason**

Why `version` differs from `authoredVersion`: `pins-changed` (a tool or agent it uses has a new version), `unpinned` (`authoredVersion` was published before pins existed), `version-taken` (`authoredVersion` is registered with other content).

string

Allowed values: pins-changed unpinned version-taken

**newVersion**

`true`: this deploy registered `version`; `false`: an earlier deploy did.

boolean

**pinChanges**

For `pins-changed`: the pins that differ from `authoredVersion`’s.

Array\<object>

One pin that differs between two versions of an agent or a flow.

object

**kind**

required

string

Allowed values: tool prompt setting agent

**id**

required

string

**from**

The earlier version’s pin; absent when it had none.

string

**to**

The later version’s pin; absent when it has none.

string

**created**

required

`true`: the promotion made this deployment (`201`). `false`: the target had this build already (`200`), and only the versions it lacked were carried.

boolean

**moved**

required

object

**packId**

string

**imageDigest**

required

string

/^sha256:\[0-9a-f]{64}$/

**agents**

required

Array\<object>

object

**id**

required

string

**version**

string

**carried**

Carried with the build: an edit of a version it ships. Absent for one it ships.

boolean

**flows**

required

Array\<object>

object

**id**

required

string

**version**

string

**carried**

Carried with the build: an edit of a version it ships. Absent for one it ships.

boolean

**tools**

required

Array\<object>

object

**id**

required

string

**version**

Absent for guardrails, which have no version.

string

**guardrails**

required

Array\<object>

object

**id**

required

string

**version**

Absent for guardrails, which have no version.

string

**leftBehind**

Edits of the build’s agents and flows that stay behind; absent when none.

Array\<object>

object

**kind**

required

`agent` or `flow`; a later runtime may add kinds, so treat an unknown one as an item not yet named.

string

**id**

required

string

**version**

required

string

**from**

required

The version its chain of edits starts from.

string

**live**

Each carried agent pinned live in the target; present only when `makeLive` was asked.

Array\<object>

object

**id**

required

string

**version**

required

string

**pinned**

required

Live now (`true`), or waiting on a gate — an approval, or a check it failed (`false`, with `gate`).

boolean

**gate**

object

**status**

required

string

Allowed values: promoted pending-approval refused superseded rejected expired

**promotionId**

required

string format: uuid

**policy**

One of:

- **object**

  object

  **id**

  required

  string

  **version**

  required

  string

- **null**

  null

**approvalId**

The approval a `pending-approval` pin waits on.

string

**checks**

Array\<object>

One of a gate’s checks, as the promotion records it.

object

**name**

required

Stable: `comparison.required`, `comparison.status`, `comparison.freshness`, `comparison.suite`, `sameContents`, `baselineIsLive`, `scopeCovered`, `evidence.<metric>.minCases|minWeight|baselineMinCases|baselineMinWeight`, `metric.<metric>.k|minCandidate|maxDrop`, `replay.maxDiverged|maxErrors|maxRefusedWrites|maxStopped`, `classWeights.restrictedOnly`.

string

**passed**

required

boolean

**message**

required

A plain sentence: what was found against what the policy asks.

string

**value**

number | string

**threshold**

number | string

##### Example

```json
{
  "deployment": {
    "endpoint": {
      "status": "pending",
      "waiting": true,
      "packEnvProblem": {
        "code": "pack-env-ambiguous"
      }
    },
    "contents": {
      "agents": [
        {
          "reason": "pins-changed",
          "pinChanges": [
            {
              "kind": "tool"
            }
          ]
        }
      ],
      "flows": [
        {
          "reason": "pins-changed",
          "pinChanges": [
            {
              "kind": "tool"
            }
          ]
        }
      ]
    }
  },
  "moved": {
    "agents": [
      {
        "carried": true
      }
    ],
    "flows": [
      {
        "carried": true
      }
    ]
  },
  "live": [
    {
      "gate": {
        "status": "promoted"
      }
    }
  ]
}
```

### 400

Malformed body (`bad-input`). Or `signature-invalid`: the deployment’s signature doesn’t verify over the fields it keeps.

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

### 403

No `admin` on the target project. Or `key-project-mismatch`: the API key or session is limited to a project, and a promotion reads one project and writes another (`details.keyProjectId`, `details.projectId`). Or `signer-not-trusted`: the key that signed the build is no longer on the tenant’s trust list (`details.signerKeyId`).

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

`deployment-not-found`: no deployment with that id in this tenant, or one in a project you don’t read.

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

`promotion-not-next-environment`: the target isn’t the next environment of the deployment’s order, or the deployment’s environment is last or in no order (`details.position`, the next environment’s place; `details.nextProjectId`, when you can read it). `promotion-values-not-ready`: values the build needs aren’t ready in the target, each in `details.values` (`DeploymentValue`). `deployment-superseded`: the deployment no longer serves its environment, or the target’s copy no longer serves there: newer deployments serve every tool version it ships (`details.environment`, `source` or `target`; `details.newerDeploymentId`). `project-suspended`, `pack-suspended`, `tenant-suspended` or `tenant-closing`: a suspension of the source or the target (`details.environment`). Nothing is written.

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

`promotions-unsupported`: this runtime’s deployment ledger can’t promote.

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/deployments/{deploymentId}`: Fetch a signed deployment record](https://docs.kindgi.com/v0.1.10/reference/api/operations/deploymentsget.md)
- [`GET /v1/deployments/{deploymentId}/pack-env`: Show where each name a deployment's pack declares is set](https://docs.kindgi.com/v0.1.10/reference/api/operations/deploymentspackenv.md)
- [`POST /v1/deployments/{deploymentId}/secrets`: Sync secrets against a deployment](https://docs.kindgi.com/v0.1.10/reference/api/operations/deploymentssyncsecrets.md)
- [`GET /v1/deployments/{deploymentId}/values`: List the values a deployment needs in a project](https://docs.kindgi.com/v0.1.10/reference/api/operations/deploymentsvalueslist.md)
- [Error code `bad-input`](https://docs.kindgi.com/v0.1.10/reference/errors.md#bad-input)
- [Error code `deployment-not-found`](https://docs.kindgi.com/v0.1.10/reference/errors.md#deployment-not-found)
- [Error code `deployment-superseded`](https://docs.kindgi.com/v0.1.10/reference/errors.md#deployment-superseded)
- [Error code `key-project-mismatch`](https://docs.kindgi.com/v0.1.10/reference/errors.md#key-project-mismatch)
- [Error code `pack-suspended`](https://docs.kindgi.com/v0.1.10/reference/errors.md#pack-suspended)
- [Error code `project-suspended`](https://docs.kindgi.com/v0.1.10/reference/errors.md#project-suspended)
- [Error code `promotion-not-next-environment`](https://docs.kindgi.com/v0.1.10/reference/errors.md#promotion-not-next-environment)
- [Error code `promotion-values-not-ready`](https://docs.kindgi.com/v0.1.10/reference/errors.md#promotion-values-not-ready)
- [Error code `promotions-unsupported`](https://docs.kindgi.com/v0.1.10/reference/errors.md#promotions-unsupported)
- [Error code `request-too-large`](https://docs.kindgi.com/v0.1.10/reference/errors.md#request-too-large)
- [Error code `signature-invalid`](https://docs.kindgi.com/v0.1.10/reference/errors.md#signature-invalid)
- [Error code `signer-not-trusted`](https://docs.kindgi.com/v0.1.10/reference/errors.md#signer-not-trusted)
- [Error code `tenant-closing`](https://docs.kindgi.com/v0.1.10/reference/errors.md#tenant-closing)
- [Error code `tenant-suspended`](https://docs.kindgi.com/v0.1.10/reference/errors.md#tenant-suspended)
- [Every error code](https://docs.kindgi.com/v0.1.10/reference/errors.md)
