Removals API
NOTE
These are the internal routes the workspace window uses. They are not a public API and may change.
These routes sit under /api/workspaces/ in the workspace itself. They are not the /ox-api/ surface in the
REST API. For the person-facing flow, see Removals;
for every refusal and its sentence, see A removal was refused.
Overview
A removal is staged by a Save or an accepted proposal, waits on a list kept with the workspace, and runs only at Deploy. Deploy is bound to a plan hash: the plan you reviewed must still be the plan when you confirm.
Any workspace member can accept a proposal; some changes (access, licences, connected-app requests) need a management right. The same holds for a Save.
| Who | Needed for |
|---|---|
| A workspace member | Saving, and accepting a proposal |
An owner, or Workspace.Access.Manage | Saving or accepting a change to access records or a connected-app request; archiving the workspace |
Licenses.Manage | Saving or accepting a change to licences |
Workspace.Deploy | The deploy plan, Deploy, and reading a deploy run |
A workspace's owners hold Licenses.Manage and Workspace.Deploy with no access card. A call is still
capped by the rights its token carries, so an API key scoped without them is refused.
Deploy plan
GET /api/workspaces/commit/deploy-plan
Returns what a Deploy would do now, including every staged removal and a PlanHash.
| Status | Code | When |
|---|---|---|
| 403 | DEPLOY_NOT_ALLOWED | The caller lacks Workspace.Deploy |
| 503 | CHECKS_UNAVAILABLE | The removal checks could not run, so no plan could be built |
Deploy
POST /api/workspaces/commit/deploy
Body: ConfirmedPlanHash, the PlanHash of the plan the person confirmed.
| Status | Code | When |
|---|---|---|
| 403 | DEPLOY_NOT_ALLOWED | The caller lacks Workspace.Deploy |
| 409 | DEPLOY_PLAN_CHANGED | Removals are waiting or records are moving to your private cloud, and the confirmed hash does not match the current plan (an older deletes body is refused the same way). The body carries the fresh Plan. Nothing was torn down |
| 409 | DEPLOY_IN_PROGRESS | Another deploy holds this workspace |
| 409 | MOVE_HELD | A record would move to your private cloud and its kind cannot move yet. Nothing was deployed |
| 503 | CHECKS_UNAVAILABLE | The removal checks could not run, so nothing was deployed |
A removal that needs a copy of its data taken first is not refused by status: it comes back as an excluded
entry in the response, with the code DATA_ARCHIVE_GATED, and stays on the list.
Save
POST /api/workspaces/commit
Body: eac (the workspace) and StageDeletes (removals to stage). Restoring a waiting removal is a Save
that clears its entry.
| Status | Code | When |
|---|---|---|
| 400 | RECORD_STAGED_FOR_DELETE | The Save changes a record that is waiting to be removed |
| 400 | STAGE_ON_ACTUATED_SAVE | A removal was added to a setup-window Save that also builds in your cloud |
| 400 | STAGE_DELETES_SHAPE | A removal does not say what it removes |
| 400 | any removal check code | A refusal from the removal checks |
| 409 | TEARDOWN_STARTED | The removal being restored has already started |
| 409 | DEPLOY_IN_PROGRESS | A deploy holds this workspace |
| 503 | CHECKS_UNAVAILABLE | The checks could not load, so nothing was committed |
Removal check
POST /api/workspaces/commit/removal-check
Body: Records, a list of { Kind, Lookup } (at most 50). Answers, for each record, whether a delete
would remove it at once (GoesAway) or leave it waiting for Deploy, with the reason. The canvas asks this
before a delete; the Save decides again on its own.
Accept a proposal
POST /api/workspaces/proposals/{group}/{bundle}/accept
Body: ConfirmDeletes, required when the bundle removes records.
| Status | Code | When |
|---|---|---|
| 400 | DELETE_CONFIRM_REQUIRED | The bundle removes records and ConfirmDeletes was not sent |
| 403 | NOT_A_MEMBER | The caller is not a member of this workspace |
| 403 | ACCESS_MANAGE_REQUIRED | The bundle changes access records and the caller is not an owner and lacks Workspace.Access.Manage |
| 403 | ACCESS_RIGHT_REQUIRED | The bundle changes licences and the caller lacks Licenses.Manage |
| 400 | FROM_SURFACE_NOT_SUPPORTED | The bundle removes a kind from one surface that is removed only as a whole record |
| 409 | ALREADY_STAGED | The record is already waiting for the next deploy |
| 409 | TARGET_NOT_FOUND | The record is no longer in this workspace |
| 409 | any other removal check code | A refusal from the removal checks |
| 409 | DEPLOY_IN_PROGRESS | A deploy holds this workspace |
| 503 | CHECKS_UNAVAILABLE | The checks could not run, so nothing was accepted |
Accepting stages a removal that waits for Deploy; a record that runs nothing in Azure, or was never built, is removed at accept.
Archive a workspace
DELETE /api/workspaces/archive
| Status | Code | When |
|---|---|---|
| 403 | ACCESS_MANAGE_REQUIRED | The caller is not an owner and lacks Workspace.Access.Manage (the plan read needs the same) |
| 409 | WORKSPACE_ARCHIVE_BLOCKED | Removals are still waiting for the next deploy |
| 409 | DEPLOY_IN_PROGRESS | A deploy holds this workspace |
| 409 | PROVENANCE_WORM_ACTIVE | A Provenance scope is under a locked immutability policy |
| 409 | ARCHIVE_PLAN_CHANGED | The archive plan changed since it was shown |
GET /api/workspaces/archive returns the archive plan.
History
GET /api/workspaces/commit/statuses
The last 20 commits, each with the intent it was recorded with. The Deploy window's Deployments and Saves read this.
GET /api/workspaces/commit/deploy-runs/{runId}
A running or finished deploy, step by step. Needs Workspace.Deploy.