> ## Documentation Index
> Fetch the complete documentation index at: https://docs.autocalls.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Preview data migration

> See what a migration would copy, and what would stop it, without changing anything

This endpoint is a dry run of a migration: it returns what the selection would copy, the counts, the warnings and anything that would stop it, and writes nothing. It is the **Preview Migration** button of the Data Migration page of your administration panel. It is optional: [Start data migration](https://docs.autocalls.ai/api-reference/white-label/start-data-migration.md) runs the same checks and refuses a selection that cannot run.

> [!NOTE]
>
> This endpoint is available to the **account owner** (with an active plan) and to team members with **Platform Admin**. Other users receive a 403 Forbidden error. The owner's own account can be a source or a destination only for the owner and for team members with **Allow impersonate owner**. Users outside your platform are refused with 422.

### What the preview checks

* **The users and the IDs**: both users must be users you can pick, and every ID must be one that [Get data migration items](https://docs.autocalls.ai/api-reference/white-label/get-data-migration-items.md) offers for the source user. These errors return 422.
* **The destination user's limits**, for the whole selection at once: assistants, knowledgebases, tools and voices, counting the knowledgebases and tools the assistants bring with them. Those already copied to this destination user by an earlier migration are reused, so they do not count.
* **Every phone number**: a WhatsApp sender on the number, a missing or cancelled subscription, a number already shared with the destination user, and assistants that use the number but are not migrated with it.
* **The automation flows**: each flow the selection would copy must be in the source user's automation workspace, and the destination user must have a workspace. See [Automation flows](https://docs.autocalls.ai/api-reference/white-label/start-data-migration.md#automation-flows).

Whatever would stop the migration is listed in `blocking_errors`, with `can_proceed` set to `false`, and the response is still 200. `items` is then empty. Fix the selection, or the destination user's limits, and preview again.

The preview cannot predict everything: a document that fails to copy, an automation flow that fails to copy, and changes made between the preview and the start. A migration checks the selection again when it starts running.

Automation flows are checked within 60 seconds. Flows that could not be checked in time are listed in `flows_not_verified`, are left out of `items`, and are checked again when the migration runs.

### Request Body

The same body as [Start data migration](https://docs.autocalls.ai/api-reference/white-label/start-data-migration.md#request-body).

**source\_user\_id** `integer` *required*

The user to copy from, from [List data migration users](https://docs.autocalls.ai/api-reference/white-label/list-data-migration-users.md).

**destination\_user\_id** `integer` *required*

The user to copy to, from [List data migration users](https://docs.autocalls.ai/api-reference/white-label/list-data-migration-users.md). It must be another user than the source.

**assistant\_ids** `integer[]`

Assistants of the source user, from [Get data migration items](https://docs.autocalls.ai/api-reference/white-label/get-data-migration-items.md). Up to 1000.

**phone\_number\_ids** `integer[]`

Phone numbers of the source user. Up to 1000.

**knowledgebase\_ids** `integer[]`

Knowledgebases to copy on their own. Up to 1000.

**tool\_ids** `integer[]`

Tools to copy on their own. Up to 1000.

**widget\_ids** `integer[]`

Widgets of the source user. Up to 1000.

**dashboard\_slugs** `string[]`

Dashboards of the source user, by `slug`. Up to 100, each at most 100 characters.

**flow\_ids** `string[]`

Automation flows of the source user, from [List data migration flows](https://docs.autocalls.ai/api-reference/white-label/list-data-migration-flows.md). Up to 50. Each ID has only letters, digits, `-` and `_`, and at most 64 characters.

**voice\_ids** `integer[]`

The source user's own voices, to copy on their own. Up to 1000.

**assistant\_options** `object`

How the migrated assistants are copied, for every assistant of the migration.

**assistant\_options properties**

**include\_knowledgebase** `boolean` (default: true)

Copy each assistant's knowledgebase with it.

**include\_custom\_tools** `boolean` (default: true)

Copy each assistant's custom tools with it.

**include\_postcall\_flows** `boolean` (default: true)

Copy the automation flows behind the post-call and conversation-ended webhooks.

**include\_inbound\_flows** `boolean` (default: true)

Copy the automation flows behind the inbound, chat conversation and WhatsApp voice webhooks.

**voice\_handling** `string` (default: reference)

`reference` or `clone`.

At least one list must have an item. Unknown fields are refused.

### Response

**data** `object`

The preview

**data properties**

**can\_proceed** `boolean`

`true` when nothing would stop the migration

**blocking\_errors** `object[]`

What would stop it: `item_type` (`assistant`, `phone_number`, `knowledgebase`, `tool`, `voice` or `flow`), `item_id` (the ID, the flow ID, or `null` for a limit of the destination user) and `message`

**counts** `object`

What the selection copies, with what the assistants bring with them, without duplicates: `assistants`, `phone_numbers`, `knowledgebases`, `tools`, `widgets`, `dashboards`, `flows`, `voices` and `total`. `flows` counts every automation flow, and `flows_from_assistants` those behind the assistants' webhooks only, which `total` does not count twice

**warnings** `string[]`

Every warning of the selection, without duplicates, with the notes about the automation flows

**flows\_not\_verified** `string[]`

The automation flow IDs that could not be checked in time

**items** `object[]`

What the migration would do with each item you selected, in the order it runs

**item properties**

**type** `string`

`assistant`, `phone_number`, `knowledgebase`, `tool`, `widget`, `dashboard`, `voice` or `flow`

**source\_id** `integer`

The item's ID. Dashboards have `slug` instead, and automation flows `flow_id`

**name** `string | null`

The item's name, or the phone number

**action** `string`

`copy`; for phone numbers `grant` (shared) or `transfer` (changes owner); for voices `clone`

**warnings** `string[]`

The item's warnings

**includes** `object[]`

For assistants, what comes with them: `type` (`knowledgebase`, `tool` or `voice`), `source_id`, `name`, and `reused`, `true` when an earlier copy is used or the voice is used as it is. Empty for the other types

```json 200 Can Proceed theme={null}
{
  "data": {
    "can_proceed": true,
    "blocking_errors": [],
    "counts": {
      "assistants": 1,
      "phone_numbers": 1,
      "knowledgebases": 1,
      "tools": 1,
      "widgets": 0,
      "dashboards": 0,
      "flows": 1,
      "flows_from_assistants": 1,
      "voices": 0,
      "total": 5
    },
    "warnings": [
      "The copy has no phone number unless a number is migrated with it.",
      "Automate webhooks will be re-pointed or cleared; other webhook URLs are kept.",
      "Automate flow triggers will be updated to reference the new assistant automatically",
      "Voice will reference source user's voice - may become unavailable if source deletes it",
      "OAuth connections (Google, Slack, etc.) are not copied with Automate flows. Each step uses the destination user's own connection to the same app, so the destination user must connect any app that is missing.",
      "Automate flows are copied as unpublished drafts — the destination user must review their connections and publish each flow from the Automate page before it runs."
    ],
    "flows_not_verified": [],
    "items": [
      {
        "type": "assistant",
        "source_id": 101,
        "name": "Bella",
        "action": "copy",
        "warnings": [
          "The copy has no phone number unless a number is migrated with it.",
          "Automate webhooks will be re-pointed or cleared; other webhook URLs are kept.",
          "Automate flow triggers will be updated to reference the new assistant automatically",
          "Voice will reference source user's voice - may become unavailable if source deletes it"
        ],
        "includes": [
          { "type": "knowledgebase", "source_id": 21, "name": "Bella FAQ", "reused": false },
          { "type": "tool", "source_id": 31, "name": "Check availability", "reused": false },
          { "type": "voice", "source_id": 3, "name": "Bella voice", "reused": true }
        ]
      },
      {
        "type": "phone_number",
        "source_id": 7,
        "name": "+14155550123",
        "action": "grant",
        "warnings": [],
        "includes": []
      }
    ]
  }
}
```

```json 200 Blocked theme={null}
{
  "data": {
    "can_proceed": false,
    "blocking_errors": [
      {
        "item_type": "assistant",
        "item_id": null,
        "message": "Destination user has reached their assistants limit (4/5)."
      },
      {
        "item_type": "phone_number",
        "item_id": 7,
        "message": "Phone number is attached to 1 assistant(s). Unassign it first."
      },
      {
        "item_type": "flow",
        "item_id": null,
        "message": "Destination user has no automate project configured."
      }
    ],
    "counts": {
      "assistants": 2,
      "phone_numbers": 1,
      "knowledgebases": 0,
      "tools": 0,
      "widgets": 0,
      "dashboards": 0,
      "flows": 1,
      "flows_from_assistants": 0,
      "voices": 0,
      "total": 4
    },
    "warnings": [
      "Standalone automate flow triggers will have the assistant selection cleared. The destination user must reconfigure which assistant triggers each flow."
    ],
    "flows_not_verified": [],
    "items": []
  }
}
```

```json 401 Unauthenticated theme={null}
{
  "message": "Unauthenticated."
}
```

```json 403 Not Administrator theme={null}
{
  "message": "You are not an administrator."
}
```

```json 403 No Data Migration Access theme={null}
{
  "message": "You do not have access to data migration."
}
```

```json 422 Missing Source User theme={null}
{
  "message": "Please select a source user.",
  "errors": {
    "source_user_id": ["Please select a source user."]
  }
}
```

```json 422 Not Your Users theme={null}
{
  "message": "Choose users of your platform.",
  "errors": {
    "source_user_id": ["Choose users of your platform."]
  }
}
```

```json 422 Same User theme={null}
{
  "message": "Cannot migrate to the same user.",
  "errors": {
    "destination_user_id": ["Cannot migrate to the same user."]
  }
}
```

```json 422 Nothing Selected theme={null}
{
  "message": "Please select at least one item to migrate.",
  "errors": {
    "selection": ["Please select at least one item to migrate."]
  }
}
```

```json 422 Not Offered theme={null}
{
  "message": "Some selected items do not belong to the source user.",
  "errors": {
    "phone_number_ids": ["Some selected items do not belong to the source user."]
  }
}
```

```json 422 Too Many IDs theme={null}
{
  "message": "The assistant ids field must not have more than 1000 items.",
  "errors": {
    "assistant_ids": ["The assistant ids field must not have more than 1000 items."]
  }
}
```

```json 422 Too Many Automations theme={null}
{
  "message": "This selection copies more than 100 automations. Split it into smaller migrations.",
  "errors": {
    "flow_ids": ["This selection copies more than 100 automations. Split it into smaller migrations."]
  }
}
```

```json 422 Unsupported Field theme={null}
{
  "message": "The tenant_id field is not supported.",
  "errors": {
    "tenant_id": ["The tenant_id field is not supported."]
  }
}
```

```json 429 Too Many Requests theme={null}
{
  "message": "Too Many Attempts."
}
```

```json 429 Platform Limit theme={null}
{
  "message": "Too many data migration requests on your platform. Try again in 42 seconds."
}
```

### Rate limit

The data migration endpoints count toward the limit of 60 requests per minute for each account that the administration endpoints share. The preview also has its own limit: 10 per minute for each account, and 10 per minute for your whole platform, counted together for the API, the AI connector and the Data Migration page. Above a limit it returns `429`, and the `Retry-After` response header tells you how many seconds to wait.

### Example

```bash theme={null}
curl -X POST https://app.autocalls.ai/api/white-label/data-migration/preview \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "source_user_id": 12,
    "destination_user_id": 34,
    "assistant_ids": [101],
    "phone_number_ids": [7]
  }'
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.