---
title: "Plan a database schema promotion"
method: POST
path: "/api/v1/databases/{databaseId}/branches/{branchId}/schema-promotions"
tags: ["Databases"]
---

# Plan a database schema promotion

`POST /api/v1/databases/{databaseId}/branches/{branchId}/schema-promotions`

## Request

- Base URL: `https://app.khotan.com`
- URL: `https://app.khotan.com/api/v1/databases/{databaseId}/branches/{branchId}/schema-promotions`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-api-key`

Compares a ready branch schema against the production database schema, records a schema-only promotion plan, validates generated SQL on a temporary provider branch, and returns the persisted plan. It never copies branch data to production.

## Path parameters

- `databaseId` string, required
- `branchId` string, required

## Response `201`

The persisted promotion plan. Status is ready only when SQL validation passes and no blocked changes exist.

- object
  - `id` string, required
  - `databaseId` string, required
  - `branchId` string, required
  - `status` 'planning' | 'ready' | 'blocked' | 'applying' | 'applied' | 'failed', required
  - `sourceSchemaHash` string, required
  - `targetSchemaHash` string, required
  - `summary` object, required
    - `statementCount` integer, required
    - `createdSchemas` string[], required
    - `createdTypes` string[], required
    - `createdTables` string[], required
    - `addedColumns` string[], required
    - `createdIndexes` string[], required
    - `createdConstraints` string[], required
    - `blockedCount` integer, required
  - `blockedChanges` object[], required
    - `code` string, required
    - `message` string, required
    - `objectType` 'schema' | 'table' | 'column' | 'constraint' | 'index' | 'type', required
    - `objectName` string, required
    - `details` object
  - `sql` string, required
  - `failureState` object, nullable, required
    - `code` 'blocked_changes' | 'schema_unavailable' | 'validation_failed' | 'schema_changed' | 'apply_failed' | 'provider_unavailable' | 'provider_rejected' | 'internal_error', required
    - `message` string, required
  - `failedStatementIndex` integer, nullable, required
  - `createdAt` string, required
  - `updatedAt` string, required
  - `validatedAt` string, nullable, required
  - `appliedAt` string, nullable, required
  - `failedAt` string, nullable, required

## Other responses

- `401`: Authentication is missing or invalid.
- `403`: The caller is not permitted to perform this action.
- `404`: The resource was not found.
- `429`: Too many requests; retry after the indicated delay.

---

[API](https://skmtc.dev/khotan/apis/khotan-api.md) - [All operations](https://skmtc.dev/khotan/apis/khotan-api/llms.txt) - [OpenAPI document](https://skmtc.dev/khotan/apis/khotan-api/revisions/90b512a53e42?raw)
