> ## 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.

# Start data migration

> Copy assistants, phone numbers and more from one of your users to another, in the background

This endpoint starts a migration from one user of your platform to another. It is the **Execute Migration** button of the Data Migration page of your administration panel, with the same rules. The migration runs in the background: the request returns at once with the migration's `id` and the status `queued`, and [Get data migration](https://docs.autocalls.ai/api-reference/white-label/get-data-migration.md) shows its progress and its results.

> [!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.

### How it runs

1. **Checks.** The selection is checked as in [Preview data migration](https://docs.autocalls.ai/api-reference/white-label/preview-data-migration.md): the two users, the IDs, the destination user's limits for the whole selection, every phone number and the automation flows. If anything would stop the migration part-way, nothing starts and the request returns 422 with the `blocking_errors`. You do not need to call the preview first.
2. **One at a time.** Your platform runs one migration at a time. While another one is queued or running, the request returns 409: start again when it has finished.
3. **Queued.** Otherwise the migration is recorded and returned with the status `queued`.
4. **Checked again.** When it starts running, the migration checks your access, the selection and the limits again, because they may have changed while it waited. If something no longer fits, it ends `failed`, with the reason in `error`, and nothing is copied.
5. **Copying.** Items are copied in this order: assistants, phone numbers, knowledgebases, tools, widgets, dashboards, voices, then automation flows. The results are saved after each item. No new item starts after 10 minutes: the items left are listed in `not_started`.
6. **Done.** The status becomes `completed`, `completed_with_issues` or `failed`, and the administrator who started it gets a notification in the administration panel.

Poll [Get data migration](https://docs.autocalls.ai/api-reference/white-label/get-data-migration.md) with the returned `id`, for example every few seconds, until the status is no longer `queued` or `running`.

### What each type does

* **Assistants** are copied to the destination user with a new ID. A copy has no phone number unless its number is migrated with it: the number is then attached to the copy, which can take and place calls on it right away. Depending on `assistant_options`, the copy also gets:

  * its knowledgebase and custom tools, copied with it. When they were already copied to this destination user by an earlier migration, that copy is reused;
  * its voice, used as it is or copied (`voice_handling`);
  * its greeting audio and its secondary languages;
  * the automation flows behind its webhooks, copied as unpublished drafts that start from the new assistant. With the option off, those webhooks are left empty on the copy.

  Webhook URLs that do not point to one of the source user's automation flows are kept as they are, and keep receiving data from the copy.
* **Normal phone numbers are shared.** The source user keeps the number and keeps paying for it, and only the destination user can use it. The access ends with the number's subscription.
* **SIP and Caller ID numbers change owner.** The number moves to the destination user, with its trunk settings and caller ID verification, and the source user's assistants on it are unassigned.
* **Knowledgebases** are copied, and their documents are processed again in the background. A knowledgebase already copied to this destination user by an earlier migration is reused, without the changes made since.
* **Tools** are copied, and reused like knowledgebases. The flow behind an automation tool is copied too. When it cannot be copied, the copy's endpoint is left empty.
* **Widgets** are copied. A widget that shows one assistant shows its copy when that assistant is migrated in the same migration; otherwise it shows all the destination user's assistants until it is set up again. Campaign filters are cleared.
* **Dashboards** are copied with their own copies of their widgets, under a new slug. They do not become the destination user's default dashboard.
* **Voices** are copied as a new voice of the destination user that uses the same provider voice. A voice listed in `voice_ids` counts against the destination user's cloned voices limit.
* **Automation flows** are copied as unpublished drafts. Each step uses the destination user's connection to the same app: add the missing connections, then publish the flow. A flow copied on its own has its assistant selection cleared.

Labels, campaigns, version history, MCP servers, WhatsApp senders and the widget avatar are not copied. Copied tools keep their headers and keep calling their endpoints. The source user's campaigns keep the phone numbers in their list.

### Automation flows

An automation flow is copied only when it is in the source user's automation workspace and the destination user has a workspace too:

* **Behind an assistant's webhook or a tool's endpoint**, a flow that does not meet these conditions is not copied, and the webhook or endpoint is left empty on the copy, with a warning.
* **In `flow_ids`**, a flow that is not in the source user's workspace, or a source or destination user without a workspace, blocks the migration with 422.
* Each flow is checked before anything is copied, within 60 seconds. A flow that could not be checked in time is not copied, with a warning.
* One migration copies at most 100 automation flows in total, counting those behind the assistants' webhooks, the tools' endpoints and `flow_ids`. Above that, split the selection into smaller migrations.

### Running it again

Each migration copies again: migrating the same assistant, widget, dashboard or flow twice gives two copies. Knowledgebases and tools are the exception: one already copied to the same destination user is reused. A phone number already shared with the destination user, or no longer owned by the source user, is refused.

### When part of it fails

Each item is copied completely or not at all, but a migration is not: a failed item, or one that did not start, does not undo the others. The migration then ends `completed_with_issues`, or `failed` after an unexpected error. In both cases the `results` of [Get data migration](https://docs.autocalls.ai/api-reference/white-label/get-data-migration.md) list what was copied, with the history row IDs to undo each item with [Roll back data migration](https://docs.autocalls.ai/api-reference/white-label/rollback-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, from [Get data migration items](https://docs.autocalls.ai/api-reference/white-label/get-data-migration-items.md). Up to 1000. A number used by an assistant you migrate is attached to its copy.

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

Knowledgebases to copy on their own. Up to 1000. The knowledgebase of a migrated assistant is copied with it when `include_knowledgebase` is on, so you do not need to list it.

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

Tools to copy on their own. Up to 1000. The tools of a migrated assistant are copied with it when `include_custom_tools` is on.

**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. Any flow of the source user's workspace can be sent, also one the listing did not reach.

**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. These options apply to every assistant of the migration.

**assistant\_options properties**

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

Copy each assistant's knowledgebase with it. Off, the copy has no knowledgebase.

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

Copy each assistant's custom tools with it. Off, the copy has no custom tools.

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

Copy the automation flows behind the post-call and conversation-ended webhooks. Off, those webhooks are left empty on the copy.

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

Copy the automation flows behind the inbound, chat conversation and WhatsApp voice webhooks. Off, those webhooks are left empty on the copy.

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

`reference`: the copy uses the source user's voice. `clone`: the destination user gets their own copy of the voice. Voices of the platform are always used as they are.

At least one list must have an item. Unknown fields are refused, and then nothing is started.

### Response

**message** `string`

`Migration started.`

**data** `object`

The migration, as in [Get data migration](https://docs.autocalls.ai/api-reference/white-label/get-data-migration.md), with the status `queued`. Its `counts`, `succeeded` and `failed` are `null` and its `results` empty until it runs

```json 200 Migration Started theme={null}
{
  "message": "Migration started.",
  "data": {
    "id": 55,
    "status": "queued",
    "channel": "api",
    "error": null,
    "initiated_by": { "id": 5, "name": "Alex Morgan" },
    "source_user": { "id": 12, "name": "Jane Cooper" },
    "destination_user": { "id": 34, "name": "John Smith" },
    "counts": null,
    "succeeded": null,
    "failed": null,
    "results": [],
    "warnings": [],
    "not_started": [],
    "created_at": "2026-11-03T10:15:00+00:00",
    "started_at": null,
    "finished_at": null
  }
}
```

```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 409 Already Running theme={null}
{
  "message": "A migration is already running on your platform. Wait for it to finish, then try again."
}
```

```json 422 Cannot Start theme={null}
{
  "message": "This migration cannot start.",
  "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 has an active WhatsApp sender. Detach it before migrating."
    }
  ]
}
```

```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": {
    "assistant_ids": ["Some selected items do not belong to the source user."]
  }
}
```

```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 Invalid Voice Handling theme={null}
{
  "message": "The assistant_options.voice_handling field accepts only: reference, clone.",
  "errors": {
    "assistant_options.voice_handling": ["The assistant_options.voice_handling field accepts only: reference, clone."]
  }
}
```

```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. Starting a migration also has its own limit: 5 per minute for each account, and 5 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: Copy an assistant with its phone number

```bash theme={null}
curl -X POST https://app.autocalls.ai/api/white-label/data-migration/runs \
  -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],
    "assistant_options": {
      "voice_handling": "reference"
    }
  }'
```

### Example: Copy assistants without their automations, with their own voices

```bash theme={null}
curl -X POST https://app.autocalls.ai/api/white-label/data-migration/runs \
  -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, 102],
    "assistant_options": {
      "include_postcall_flows": false,
      "include_inbound_flows": false,
      "voice_handling": "clone"
    }
  }'
```

### Example: Copy a dashboard and two automation flows

```bash theme={null}
curl -X POST https://app.autocalls.ai/api/white-label/data-migration/runs \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "source_user_id": 12,
    "destination_user_id": 34,
    "dashboard_slugs": ["sales"],
    "flow_ids": ["Ab3xK9pQ2mZ7", "Qw8eR4tY6uI1"]
  }'
```


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