---
title: "Move a business organization into a new tenant (Greentally staff only)"
method: POST
path: "/internal/tenant-moves"
tags: ["PlatformOps"]
---

# Move a business organization into a new tenant (Greentally staff only)

`POST /internal/tenant-moves`

Requires partner.ops (API keys and impersonation sessions are always refused); 404 while PARTNERS_ENABLED is off. dryRun is required: true answers the plan and writes nothing; false records the move and runs it (planned, clerk_org_created, relinked, members_synced, done). A failed step answers 502 MOVE_STEP_FAILED with the move id and the state it stopped after; fix the cause and resume. Refusals answer 409 with the code (DEFAULT_ORGANIZATION, ORGANIZATION_ARCHIVED, MOVE_OPEN with the open move's id in details.moveId, DOCUMENT_JOB_RUNNING, REPORT_GENERATION_RUNNING, SUPPORT_ACCESS_OPEN, NO_MEMBERS, PARTNER_REQUIRED, UNSURVEYED_ACCOUNT_TABLE, CLERK_SLUG_TAKEN when the client slug belongs to a Clerk organization this move did not create). Audited (tenant_move.start, tenant_move.relink, tenant_move.sweep, tenant_move.done).

## Request body

- TenantMoveRequest
  - `clientName` string, required
  - `clientSlug` string
  - `dryRun` boolean, required
  - `mode` 'partner' | 'standalone', required
  - `organizationId` string, required
  - `partnerId` string — Required in partner mode
  - `reason` string — Required unless dryRun

## Response `200`

The plan (dry run) or the finished move

- TenantMoveResponse
  - `data` TenantMove, required
    - `clerkOrganizationId` string
    - `createdAt` string, date-time
    - `dryRun` boolean, required
    - `error` string — The last failed step's error; cleared when a step succeeds
    - `id` string
    - `mode` 'partner' | 'standalone', required
    - `organizationId` string, required
    - `partnerId` string
    - `plan` object, required — organization, source, target, users (userId, email, name, currentRole, partnerRole, clerkRole), customRoles, pendingInvitations, rowCounts by table, warnings, reason. After the relink it is the plan rebuilt inside the relink transaction, with the row counts it re-pointed.
    - `state` 'planned' | 'clerk_org_created' | 'relinked' | 'members_synced' | 'done' | 'failed', required
    - `targetAccountId` string
    - `updatedAt` string, date-time

## Other responses

- `400` — Bad Request
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not Found
- `409` — Conflict
- `502` — A step failed; resume the move
- `503` — Clerk is not configured

## Changes

- **2026-10-06** `461a0ebc7731` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/greentally/apis/esgai-api/changes/internal/tenant-moves/post.md)

---

[API](https://skmtc.dev/greentally/apis/esgai-api.md) · [All operations](https://skmtc.dev/greentally/apis/esgai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/greentally/apis/esgai-api/revisions/461a0ebc7731?raw)
