# organization.migration.receive

Prepare an empty destination organization for a migration and freeze its writes. Auth accounts and credentials are not imported. Explicit replaceSetup allows replacing only initial settings and categories.

`POST /api/v1/accounting/organization.migration.receive`

Permissions: `accounting:read`, `accounting:write`, `accounting:admin` · Roles: admin

Not available over MCP: Organization data moves need administrator sign-ins at both installations and an explicit cutover in Settings or the CLI.

## Fields

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `id` | string (ID) | Yes | The record's ID. |
| `manifest` | object | Yes | No other fields. |
| `manifest.version` | 1 | Yes |  |
| `manifest.organizationId` | string | Yes | The company to work in, for people who belong to more than one. API keys belong to one company. Matches ^[A-Za-z0-9_-]{1,100}$. |
| `manifest.tables` | array of objects | Yes | at most 2000 items. |
| `manifest.tables[].name` | string | Yes | A display name. Matches ^[a-z_][a-z0-9_]{0,62}$. |
| `manifest.tables[].columns` | array of objects | Yes | at most 500 items. |
| `manifest.tables[].columns[].name` | string | Yes | A display name. Matches ^[a-z_][a-z0-9_]{0,62}$. |
| `manifest.tables[].columns[].type` | string | Yes | at most 200 characters. |
| `manifest.tables[].columns[].required` | boolean | Yes |  |
| `manifest.tables[].columns[].hasDefault` | boolean | Yes |  |
| `manifest.tables[].columns[].generated` | boolean | Yes |  |
| `manifest.tables[].rows` | integer | Yes | 0 to 100000000. |
| `manifest.files` | array of objects | Yes | at most 100000 items. |
| `manifest.files[].bucket` | string | Yes | at most 100 characters. |
| `manifest.files[].path` | string | Yes | at most 2048 characters. |
| `manifest.files[].size` | integer | Yes | 0 to 100000000. |
| `manifest.excluded` | array of objects | Yes | at most 2000 items. |
| `manifest.excluded[].table` | string | Yes | Matches ^[a-z_][a-z0-9_]{0,62}$. |
| `manifest.excluded[].rows` | integer | Yes | 0 to 100000000. |
| `manifest.blockers` | array of strings | Yes | at most 2000 items; each at most 500 characters. |
| `manifest.userIds` | array of strings | Yes | A list of record IDs. at most 10000 items; each at most 200 characters. |
| `peerHost` | string (uri) | Yes | at most 2000 characters. |
| `identityMap` | map | Yes |  |
| `replaceSetup` | boolean |  | Default `false`. |
| `dryRun` | boolean |  | Default `false`. |

## Example request

```bash
curl https://app.getoatmilk.com/api/v1/accounting/organization.migration.receive \
  -H "Authorization: Bearer $OATMILK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "manifest": {
    "version": 1,
    "organizationId": "organization_id",
    "tables": [
      {
        "name": "name",
        "columns": [
          {
            "name": "name",
            "type": "example",
            "required": true,
            "hasDefault": true,
            "generated": true
          }
        ],
        "rows": 1
      }
    ],
    "files": [
      {
        "bucket": "example",
        "path": "example",
        "size": 1
      }
    ],
    "excluded": [
      {
        "table": "table",
        "rows": 1
      }
    ],
    "blockers": [
      "example"
    ],
    "userIds": [
      "example"
    ]
  },
  "peerHost": "https://example.com/webhooks/oatmilk",
  "identityMap": {}
}'
```

Reference page: https://app.getoatmilk.com/docs/api/organization.migration.receive
