Skip to content

HTTP API / Migrate

Migrate API ​

50 operations. Paths are relative to the API host (http://localhost:5080 in local development). Every operation accepts an OIDC bearer token (Authorization: Bearer …) or a workspace API key (X-Api-Key: keel_live_…); errors are RFC 9457 Problem Details with a code (error codes). Permissions: matrix.

MethodPathSummary
GET/api/v1/workspaces/{workspaceId}/migrationsThe workspace's migrations, newest first (filter by status, search by name).
POST/api/v1/workspaces/{workspaceId}/migrationsCreate a migration from one or more registered sources (Draft).
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}The migration overview: target, stage strip, KPIs, plan versions and generated code.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}:infer-mappingsQueue mapping inference: table/column mappings, transforms and code maps proposed with confidence and evidence.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/code-mapsValue translation tables with their coverage of the profiled source values.
PUT/api/v1/workspaces/{workspaceId}/migrations/{projectId}/code-maps/{name}Create or replace a code map's pairs and default (saving accepts it).
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/executionThe write plane of a migration: write credential and its scope check, executors (migrate:execute), four-eyes, what you may do.
PUT/api/v1/workspaces/{workspaceId}/migrations/{projectId}/executors/{userId}Grant migrate:execute on this migration to an Owner, Admin or Steward (Owner/Admin).
DELETE/api/v1/workspaces/{workspaceId}/migrations/{projectId}/executors/{userId}Revoke migrate:execute on this migration (Owner/Admin).
PUT/api/v1/workspaces/{workspaceId}/migrations/{projectId}/four-eyesFour-eyes on or off: the switch then needs a second, distinct Steward or Owner (Owner/Admin).
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/generationsCode generation history, newest first.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/generationsQueue dbt / SQL generation from the approved plan version (zip; with Git delivery also a branch + pull request).
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/generations/{generationId}One code generation: files, warnings and Git delivery.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/generations/{generationId}/archiveThe generated files as a zip (root folder {migration}-plan-v{n}).
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/mappings:bulkAccept, reject or mark as needing work listed table/column mappings, or accept every proposal at or above minConfidence.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/plansEvery plan version, newest first.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/plansSnapshot the accepted mappings as the next immutable plan version (waits for a Steward or Owner).
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/plans/{planVersion}One plan version: its document and the changes since the previous version.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/plans/{planVersion}:approveApprove the latest plan version (Steward/Owner): code generation and reconciliation use it; lineage and masks are registered with Governance.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/plans/{planVersion}/diffWhat changed between two plan versions (?from=, default the previous one).
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/reconciliationsReconciliation runs, newest first.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/reconciliationsQueue a reconciliation of the approved plan: read-only aggregate queries on both sides.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/reconciliations/{runId}Summary, per-table checks, failing keys (keys only), what blocks sign-off and the exceptions.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/reconciliations/{runId}:sign-offSign off the latest reconciliation of the approved plan (Steward/Owner); 422 lists the Critical checks that still block it.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/reconciliations/{runId}/exceptionsAccept a failing check with a reason (Steward/Owner) so it no longer blocks sign-off.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runsThe migration's runs, newest first.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runsHand the approved plan to the private agent: bulk load through staging on the target, then change capture until cutover.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}Run status: the write-plane banner, load (rows, bytes, rows/s, ETA), change capture lag, per-table progress, quarantine total.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}:pauseQueue Pause for the agent (delivered with its next report).
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}:resumeQueue Resume for a paused run.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}:retryRetry failed chunks; a failed or stalled run is handed to the agent again and resumes from its last committed chunk.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/cutoverThe cutover checklist: five steps with progress, four-eyes approval, what blocks the switch, your own switch steps, the rollback window.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/cutoverOpen the cutover wizard of a syncing run.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/cutover:rollbackRoll serving back to the source during the rollback window (Steward/Owner); change capture stops.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/cutover/steps/{step}:confirmPerform the active step (FreezeSource, FinalSync, FinalReconciliation, Switch, RollbackWindow = close it), or approve it as the second person.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/quarantineQuarantined rows per table: counts and business keys only (at most 200 per table), never values.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/timelineWhat happened in the run, newest first, with who did it (a person, an agent or Keel).
PUT/api/v1/workspaces/{workspaceId}/migrations/{projectId}/scopeSet the source tables the migration covers (empty: every table). Inference, the plan, code generation, reconciliation and runs skip excluded tables. Audited; with a committed plan it commits the next plan version under the new scope.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/tablesThe workbench's table list: source → target, status, confidence, coverage and gaps.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}One table mapping with its column grid (sources, transform, target, confidence, evidence) and gaps.
PUT/api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}Set a table mapping's source table(s), join, filter, dedupe keys and load pattern; accepted.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}:acceptAccept a table mapping and its proposed columns at or above minColumnConfidence (default: all).
PUT/api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}/columns/{targetColumn}Set the source column(s) of a target column (creates the mapping for a gap column); accepted.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}/columns/{targetColumn}:previewThe SQL a column mapping compiles to in the target dialect; a draft in the body is previewed without saving.
PUT/api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}/columns/{targetColumn}/transformSet a column mapping's transform (parameters checked against the transform contract); accepted.
GET/api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}/evidenceWhy Keel proposed the table mapping, or one of its column mappings (?column=).
PUT/api/v1/workspaces/{workspaceId}/migrations/{projectId}/targetSet the target: a registered data source (harvested like any source) or a semantic model's entities.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/target:uploadSet the target from uploaded CREATE TABLE statements (.sql) or a dbt project (schema .yml files, or a zip): parsed in memory, 10 MB uploaded / 20 MB unzipped at most; the files are not kept. format: Ddl or Dbt; dialect: a SourceKind (PostgreSql, SqlServer, Snowflake…); dataSourceId optionally names the database reconciliation reads.
PUT/api/v1/workspaces/{workspaceId}/migrations/{projectId}/write-credentialRegister the separate write credential: a secret NAME on the private agent, its user and the target schemas it may write. Untested until checked.
POST/api/v1/workspaces/{workspaceId}/migrations/{projectId}/write-credential:testQueue the scope check on the agent: a credential that can write outside its schemas (or lacks what a run needs) is refused.

ListMigrationProjects ​

http
GET /api/v1/workspaces/{workspaceId}/migrations

The workspace's migrations, newest first (filter by status, search by name).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
statusqueryMigrationStatusno
searchquerystringno
pagequeryint32no
pageSizequeryint32no
StatusDescriptionBody
200OKPagedResultOfMigrationProjectSummaryDto

Response 200: PagedResultOfMigrationProjectSummaryDto

FieldTypeNotes
hasNextboolean
itemsMigrationProjectSummaryDto[]
pageint32
pageSizeint32
totalCountint64

CreateMigrationProject ​

http
POST /api/v1/workspaces/{workspaceId}/migrations

Create a migration from one or more registered sources (Draft).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes

Request body (application/json): CreateMigrationProjectRequest

FieldTypeNotes
descriptionstring?
namestring
sourceIdsuuid[]
strategyMigrationStrategyOne of LiftAndShift, Remodel, Consolidate
StatusDescriptionBody
201CreatedCreatedResponse

Response 201: CreatedResponse

FieldTypeNotes
iduuid

GetMigrationProject ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}

The migration overview: target, stage strip, KPIs, plan versions and generated code.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
StatusDescriptionBody
200OKMigrationProjectDto

Response 200: MigrationProjectDto

FieldTypeNotes
approvedPlanPlanVersionSummaryDto?
createdAtdate-time
descriptionstring?
iduuid
kpisMigrationKpisDto
lastInferenceErrorInferenceErrorDto?
latestGenerationCodeGenerationDto?
latestPlanPlanVersionSummaryDto?
mappingsInferredAtdate-time?
namestring
ownerstring
ownerNamestring?
scopeScopedTableDto[]?
signedOffAtdate-time?
signedOffBystring?
sourcesMigrationSourceDto[]
stagesMigrationStageDto[]
statusMigrationStatusOne of Draft, Mapping, Generated, Validating, SignedOff, Running, CutOver
strategyMigrationStrategyOne of LiftAndShift, Remodel, Consolidate
targetMigrationTargetDto?
updatedAtdate-time?
workspaceIduuid

InferMappings ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}:infer-mappings

Queue mapping inference: table/column mappings, transforms and code maps proposed with confidence and evidence.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
StatusDescriptionBody
202AcceptedJobAcceptedDto

Response 202: JobAcceptedDto

FieldTypeNotes
jobIduuid

ListCodeMaps ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/code-maps

Value translation tables with their coverage of the profiled source values.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
StatusDescriptionBody
200OKCodeMapDto[]

UpsertCodeMap ​

http
PUT /api/v1/workspaces/{workspaceId}/migrations/{projectId}/code-maps/{name}

Create or replace a code map's pairs and default (saving accepts it).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
namepathstringyes

Request body (application/json): UpsertCodeMapRequest

FieldTypeNotes
defaultstring?
pairsCodeMapPairRequest[]
sourceColumnstring?
StatusDescriptionBody
200OKCreatedResponse

Response 200: CreatedResponse

FieldTypeNotes
iduuid

GetMigrationExecution ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/execution

The write plane of a migration: write credential and its scope check, executors (migrate:execute), four-eyes, what you may do.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
StatusDescriptionBody
200OKMigrationExecutionDto

Response 200: MigrationExecutionDto

FieldTypeNotes
activeRunIduuid?
approvedPlanVersionint32?
canApproveboolean
canExecuteboolean
canManageExecutionboolean
executorsMigrationExecutorDto[]
fourEyesboolean
writeCredentialWriteCredentialDto?

GrantMigrationExecution ​

http
PUT /api/v1/workspaces/{workspaceId}/migrations/{projectId}/executors/{userId}

Grant migrate:execute on this migration to an Owner, Admin or Steward (Owner/Admin).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
userIdpathuuidyes
StatusDescriptionBody
204No Content—

RevokeMigrationExecution ​

http
DELETE /api/v1/workspaces/{workspaceId}/migrations/{projectId}/executors/{userId}

Revoke migrate:execute on this migration (Owner/Admin).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
userIdpathuuidyes
StatusDescriptionBody
204No Content—

SetMigrationFourEyes ​

http
PUT /api/v1/workspaces/{workspaceId}/migrations/{projectId}/four-eyes

Four-eyes on or off: the switch then needs a second, distinct Steward or Owner (Owner/Admin).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes

Request body (application/json): SetFourEyesRequest

FieldTypeNotes
enabledboolean
StatusDescriptionBody
204No Content—

ListCodeGenerations ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/generations

Code generation history, newest first.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
limitqueryint32no
StatusDescriptionBody
200OKCodeGenerationDto[]

GenerateMigrationCode ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/generations

Queue dbt / SQL generation from the approved plan version (zip; with Git delivery also a branch + pull request).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes

Request body (application/json): GenerateMigrationCodeRequest

FieldTypeNotes
deliveryCodeDelivery?
outputCodeOutputKindOne of Dbt, Sql, Both
StatusDescriptionBody
202AcceptedGenerationAcceptedDto

Response 202: GenerationAcceptedDto

FieldTypeNotes
generationIduuid
jobIduuid

GetCodeGeneration ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/generations/{generationId}

One code generation: files, warnings and Git delivery.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
generationIdpathuuidyes
StatusDescriptionBody
200OKCodeGenerationDto

Response 200: CodeGenerationDto

FieldTypeNotes
branchstring?
commitShastring?
completedAtdate-time?
contentHashstring?
deliveryCodeDeliveryOne of Download, Git
downloadUrlstring?
errorstring?
filePathsstring[]
filesint32
groupsCodeFileGroupDto[]
iduuid
outputCodeOutputKindOne of Dbt, Sql, Both
planVersionint32
pullRequestNumberint32?
pullRequestUrlstring?
requestedAtdate-time
requestedBystring
statusCodeGenerationStatusOne of Queued, Succeeded, Failed
warningsstring[]

DownloadMigrationCode ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/generations/{generationId}/archive

The generated files as a zip (root folder {migration}-plan-v{n}).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
generationIdpathuuidyes
StatusDescriptionBody
200OKbyte

BulkReviewMappings ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/mappings:bulk

Accept, reject or mark as needing work listed table/column mappings, or accept every proposal at or above minConfidence.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes

Request body (application/json): BulkReviewMappingsRequest

FieldTypeNotes
actionReviewActionOne of Accept, Reject, NeedsWork
columnMappingIdsuuid[]?
minConfidencenumber?
tableMappingIdsuuid[]?
StatusDescriptionBody
200OKBulkReviewResultDto

Response 200: BulkReviewResultDto

FieldTypeNotes
columnsint32
tablesint32

ListMigrationPlans ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/plans

Every plan version, newest first.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
StatusDescriptionBody
200OKPlanVersionSummaryDto[]

CommitMigrationPlan ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/plans

Snapshot the accepted mappings as the next immutable plan version (waits for a Steward or Owner).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes

Request body (application/json): CommitMigrationPlanRequest?

StatusDescriptionBody
201CreatedPlanCommittedDto

Response 201: PlanCommittedDto

FieldTypeNotes
versionint32

GetMigrationPlan ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/plans/{planVersion}

One plan version: its document and the changes since the previous version.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
planVersionpathint32yes
StatusDescriptionBody
200OKPlanVersionDto

Response 200: PlanVersionDto

FieldTypeNotes
changesFromPreviousPlanDiff?
documentMigrationPlanDocument
summaryPlanVersionSummaryDto

ApproveMigrationPlan ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/plans/{planVersion}:approve

Approve the latest plan version (Steward/Owner): code generation and reconciliation use it; lineage and masks are registered with Governance.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
planVersionpathint32yes
StatusDescriptionBody
204No Content—

GetMigrationPlanDiff ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/plans/{planVersion}/diff

What changed between two plan versions (?from=, default the previous one).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
planVersionpathint32yes
fromqueryint32no
StatusDescriptionBody
200OKPlanDiff

Response 200: PlanDiff

FieldTypeNotes
codeMapsAddedstring[]
codeMapsChangedstring[]
codeMapsRemovedstring[]
fromVersionint32
isEmptyboolean
strategyChangedboolean
tablesAddedstring[]
tablesChangedTableChange[]
tablesRemovedstring[]
toVersionint32

ListReconciliations ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/reconciliations

Reconciliation runs, newest first.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
limitqueryint32no
StatusDescriptionBody
200OKReconciliationSummaryDto[]

RunReconciliation ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/reconciliations

Queue a reconciliation of the approved plan: read-only aggregate queries on both sides.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
StatusDescriptionBody
202AcceptedReconciliationAcceptedDto

Response 202: ReconciliationAcceptedDto

FieldTypeNotes
jobIduuid
runIduuid

GetReconciliationReport ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/reconciliations/{runId}

Summary, per-table checks, failing keys (keys only), what blocks sign-off and the exceptions.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
200OKReconciliationReportDto

Response 200: ReconciliationReportDto

FieldTypeNotes
blockingBlockingCheckDto[]
canSignOffboolean
completedAtdate-time?
errorstring?
exceptionListCheckExceptionDto[]
exceptionsint32
failuresint32
iduuid
passedint32
planVersionint32
projectIduuid
requestedAtdate-time
requestedBystring
signedOffAtdate-time?
signedOffBystring?
sourceRowsComparedint64?
startedAtdate-time?
statusReconciliationStatusOne of Queued, Running, Completed, Failed
tablesTableReconciliationDto[]
targetRowsComparedint64?
warningsint32

SignOffReconciliation ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/reconciliations/{runId}:sign-off

Sign off the latest reconciliation of the approved plan (Steward/Owner); 422 lists the Critical checks that still block it.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
204No Content—

RecordReconciliationException ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/reconciliations/{runId}/exceptions

Accept a failing check with a reason (Steward/Owner) so it no longer blocks sign-off.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes

Request body (application/json): RecordExceptionRequest

FieldTypeNotes
checkKeystring
reasonstring
StatusDescriptionBody
204No Content—

ListMigrationRuns ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs

The migration's runs, newest first.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
limitqueryint32no
StatusDescriptionBody
200OKMigrationRunSummaryDto[]

ScheduleMigrationRun ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs

Hand the approved plan to the private agent: bulk load through staging on the target, then change capture until cutover.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes

Request body (application/json): ScheduleMigrationRunRequest

FieldTypeNotes
changeCaptureChangeCaptureNone (load only), SqlServerChangeTracking, SqlServerCdc, PostgresLogicalReplication, OracleLogMiner or IncrementalPolling. One of None, SqlServerChangeTracking, SqlServerCdc, PostgresLogicalReplication, IncrementalPolling, OracleLogMiner
chunkRowsint32?
parallelismint32?
pollIntervalSecondsint32?How often change capture polls the source when idle (1–300 s; default 5).
reportIntervalSecondsint32?How often the agent reports (1–60 s, and under half the run's lease; default 5).
StatusDescriptionBody
201CreatedMigrationRunScheduledDto

Response 201: MigrationRunScheduledDto

FieldTypeNotes
runIduuid
workIduuid

GetRunStatus ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}

Run status: the write-plane banner, load (rows, bytes, rows/s, ETA), change capture lag, per-table progress, quarantine total.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
200OKMigrationRunDto

Response 200: MigrationRunDto

FieldTypeNotes
actionsstring[]
agentPhaseAgentRunPhase?
attemptint32
completedAtdate-time?
cutoverStartedboolean
errorstring?
errorCodestring?
lastReconciliationReconciliationSummaryDto?
lastReportAtdate-time?
leaseExpiresAtdate-time
loadRunLoadDto
pendingCommandsRunCommand[]
planVersionint32
projectIduuid
quarantinedRowsint64
runIduuid
scheduledAtdate-time
scheduledBystring
stateRunStateOne of Scheduled, Loading, Syncing, Paused, ReadyForCutover, CuttingOver, Completed, RolledBack, Failed
stateLabelstring
stateReasonstring?
syncRunSyncDto
tablesRunTableDto[]
writePlaneRunWritePlaneDto

PauseMigrationRun ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}:pause

Queue Pause for the agent (delivered with its next report).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
204No Content—

ResumeMigrationRun ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}:resume

Queue Resume for a paused run.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
204No Content—

RetryFailedChunks ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}:retry

Retry failed chunks; a failed or stalled run is handed to the agent again and resumes from its last committed chunk.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
204No Content—

GetCutoverChecklist ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/cutover

The cutover checklist: five steps with progress, four-eyes approval, what blocks the switch, your own switch steps, the rollback window.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
200OKCutoverChecklistDto

Response 200: CutoverChecklistDto

FieldTypeNotes
callerCanRollBackboolean
canRollBackboolean
customerStepsstring[]
endpointsRepointedint32
forcedBystring?
fourEyesboolean
impactCutoverImpactDto?
impactErrorstring?
modelsRepointedint32
planVersionint32
reconciliationIduuid?
rollbackWindowEndsAtdate-time?
runIduuid
startedboolean
startedAtdate-time?
startedBystring?
stateRunStateOne of Scheduled, Loading, Syncing, Paused, ReadyForCutover, CuttingOver, Completed, RolledBack, Failed
stepsCutoverStepDto[]

StartCutover ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/cutover

Open the cutover wizard of a syncing run.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
204No Content—

RollbackCutover ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/cutover:rollback

Roll serving back to the source during the rollback window (Steward/Owner); change capture stops.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
204No Content—

ConfirmCutoverStep ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/cutover/steps/{step}:confirm

Perform the active step (FreezeSource, FinalSync, FinalReconciliation, Switch, RollbackWindow = close it), or approve it as the second person.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
steppathCutoverStepKindyes

Request body (application/json): ConfirmCutoverStepRequest?

StatusDescriptionBody
204No Content—

GetRunQuarantine ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/quarantine

Quarantined rows per table: counts and business keys only (at most 200 per table), never values.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
200OKRunQuarantineDto

Response 200: RunQuarantineDto

FieldTypeNotes
runIduuid
tablesQuarantineTableDto[]
totalint64

GetRunTimeline ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/runs/{runId}/timeline

What happened in the run, newest first, with who did it (a person, an agent or Keel).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
runIdpathuuidyes
StatusDescriptionBody
200OKRunTimelineDto

Response 200: RunTimelineDto

FieldTypeNotes
entriesRunTimelineEntryDto[]
planVersionint32
runIduuid

SetMigrationScope ​

http
PUT /api/v1/workspaces/{workspaceId}/migrations/{projectId}/scope

Set the source tables the migration covers (empty: every table). Inference, the plan, code generation, reconciliation and runs skip excluded tables. Audited; with a committed plan it commits the next plan version under the new scope.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes

Request body (application/json): SetMigrationScopeRequest

FieldTypeNotes
tablesScopedTableInput[]?The included source tables; null or empty covers every table of the migration's sources (F18 #36).
StatusDescriptionBody
200OKMigrationScopeSetDto

Response 200: MigrationScopeSetDto

FieldTypeNotes
includedTablesint32?
planVersionint32?

GetTableMappings ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables

The workbench's table list: source → target, status, confidence, coverage and gaps.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
statusqueryMappingStatusno
searchquerystringno
pagequeryint32no
pageSizequeryint32no
StatusDescriptionBody
200OKPagedResultOfTableMappingSummaryDto

Response 200: PagedResultOfTableMappingSummaryDto

FieldTypeNotes
hasNextboolean
itemsTableMappingSummaryDto[]
pageint32
pageSizeint32
totalCountint64

GetTableMapping ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}

One table mapping with its column grid (sources, transform, target, confidence, evidence) and gaps.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
tableMappingIdpathuuidyes
StatusDescriptionBody
200OKTableMappingDto

Response 200: TableMappingDto

FieldTypeNotes
bandConfidenceBandOne of High, Medium, Low
columnsColumnMappingDto[]
confidencenumber
coveragenumber
decidedAtdate-time?
decidedBystring?
dedupeKeysstring[]
droppedSourceColumnsSourceColumnDto[]
evidenceMigrateEvidenceDto[]
filterstring?
iduuid
incrementalColumnstring?
joinstring?
loadPatternLoadPatternOne of Full, IncrementalByKey, IncrementalByTimestamp
originOriginOne of Discovered, Inferred, LlmSuggested, UserDefined, Imported
projectIduuid
sourceColumnsSourceColumnDto[]
sourceRowCountint64?
sourcesstring[]
statusMappingStatusOne of Proposed, Accepted, Rejected, NeedsWork
targetstring
targetColumnsTargetColumnDto[]
unmappedTargetColumnsTargetColumnDto[]

EditTableMapping ​

http
PUT /api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}

Set a table mapping's source table(s), join, filter, dedupe keys and load pattern; accepted.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
tableMappingIdpathuuidyes

Request body (application/json): EditTableMappingRequest

FieldTypeNotes
dedupeKeysstring[]?
filterstring?Source WHERE predicate.
incrementalColumnstring?
joinstring?Join condition in source SQL when there are several sources.
loadPatternLoadPatternOne of Full, IncrementalByKey, IncrementalByTimestamp
sourcesstring[]Source tables as schema.table (from the migration's sources' latest scans).
StatusDescriptionBody
204No Content—

AcceptTableMapping ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}:accept

Accept a table mapping and its proposed columns at or above minColumnConfidence (default: all).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
tableMappingIdpathuuidyes

Request body (application/json): AcceptTableMappingRequest?

StatusDescriptionBody
204No Content—

EditColumnMapping ​

http
PUT /api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}/columns/{targetColumn}

Set the source column(s) of a target column (creates the mapping for a gap column); accepted.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
tableMappingIdpathuuidyes
targetColumnpathstringyes

Request body (application/json): EditColumnMappingRequest

FieldTypeNotes
notesstring?
sourcesColumnSourceRequest[]
StatusDescriptionBody
204No Content—

PreviewTransformSql ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}/columns/{targetColumn}:preview

The SQL a column mapping compiles to in the target dialect; a draft in the body is previewed without saving.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
tableMappingIdpathuuidyes
targetColumnpathstringyes

Request body (application/json): PreviewTransformRequest?

StatusDescriptionBody
200OKPreviewSqlDto

Response 200: PreviewSqlDto

FieldTypeNotes
dialectSourceKindOne of PostgreSql, SqlServer, MySql, Snowflake, BigQuery, Databricks, Oracle, Redshift
sqlstring
targetColumnstring

SetTransform ​

http
PUT /api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}/columns/{targetColumn}/transform

Set a column mapping's transform (parameters checked against the transform contract); accepted.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
tableMappingIdpathuuidyes
targetColumnpathstringyes

Request body (application/json): SetTransformRequest

FieldTypeNotes
kindTransformKindOne of None, Cast, Trim, Case, Default, CodeMap, Concat, Split, DateParse, UnitConversion, CurrencyConversion, SurrogateKey, Hash, CustomSql
parametersobject?Keys per kind as in TransformParameters (e.g. format for DateParse, codeMap for CodeMap).
StatusDescriptionBody
204No Content—

GetMappingEvidence ​

http
GET /api/v1/workspaces/{workspaceId}/migrations/{projectId}/tables/{tableMappingId}/evidence

Why Keel proposed the table mapping, or one of its column mappings (?column=).

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
tableMappingIdpathuuidyes
columnquerystringno
StatusDescriptionBody
200OKMappingEvidenceDto

Response 200: MappingEvidenceDto

FieldTypeNotes
bandConfidenceBandOne of High, Medium, Low
classificationstring?
confidencenumber
evidenceMigrateEvidenceDto[]
originOriginOne of Discovered, Inferred, LlmSuggested, UserDefined, Imported
sensitiveboolean
tableMappingIduuid
targetstring
targetColumnstring?

SetMigrationTarget ​

http
PUT /api/v1/workspaces/{workspaceId}/migrations/{projectId}/target

Set the target: a registered data source (harvested like any source) or a semantic model's entities.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes

Request body (application/json): SetMigrationTargetRequest

FieldTypeNotes
dataSourceIduuid?The target data source (Kind DataSource), or for a model the database reconciliation reads (optional).
kindTargetKindOne of DataSource, SemanticModel, UploadedSpec
modelIduuid?
StatusDescriptionBody
204No Content—

UploadMigrationTarget ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/target:upload

Set the target from uploaded CREATE TABLE statements (.sql) or a dbt project (schema .yml files, or a zip): parsed in memory, 10 MB uploaded / 20 MB unzipped at most; the files are not kept. format: Ddl or Dbt; dialect: a SourceKind (PostgreSql, SqlServer, Snowflake…); dataSourceId optionally names the database reconciliation reads.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes

Request body (multipart/form-data): object

StatusDescriptionBody
204No Content—

RegisterWriteCredential ​

http
PUT /api/v1/workspaces/{workspaceId}/migrations/{projectId}/write-credential

Register the separate write credential: a secret NAME on the private agent, its user and the target schemas it may write. Untested until checked.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes

Request body (application/json): RegisterWriteCredentialRequest

FieldTypeNotes
agentIduuidThe private agent that holds the secret and runs the migration (the sources' agent).
schemasstring[]Target schemas the credential may write (the staging schema keel_stage is added).
secretNamestringThe NAME of the write credential's secret in the agent's local store (never the secret).
usernamestring
StatusDescriptionBody
204No Content—

TestWriteCredential ​

http
POST /api/v1/workspaces/{workspaceId}/migrations/{projectId}/write-credential:test

Queue the scope check on the agent: a credential that can write outside its schemas (or lacks what a run needs) is refused.

ParameterInTypeRequiredNotes
workspaceIdpathuuidyes
projectIdpathuuidyes
StatusDescriptionBody
202AcceptedJobAcceptedDto

Response 202: JobAcceptedDto

FieldTypeNotes
jobIduuid

Anchor Keel is a working product name: one platform, a shared core and licensed modules (Keel Semantic, Keel Migrate). Documentation built from the repository — facts are derived from code, ADRs and the decisions log.