# Migrate from Daytona v0 (/docs/migrate-from-v0)

Migration from Daytona v0 moves an organization's resources to Daytona v2. When an organization is migrated, Daytona syncs its API keys, container registries, and snapshots into the organization's default project. Sandboxes are not synced: you import archived Daytona v0 sandboxes one at a time, each as a new persistent sandbox in the default project.

Snapshots arrive as named images in an older image format. Each image converts on its first Linux sandbox create, or ahead of time through [image conversion](/docs/images#convert-images). An imported sandbox boots from the last backup of its Daytona v0 sandbox and keeps the settings that Daytona v2 supports. Importing copies a sandbox and does not move it: the original keeps working on Daytona v0.

Every migration request is scoped to the organization's default project, and a request made with an API key for any other project is refused. API keys created in the default project can also be copied to Daytona v0; see [Daytona v0 key sync](/docs/api-keys). An organization shared with Daytona v0 also shares its [single sign-on](/docs/sso) configuration.

| **Resource**             | **Migration**                                                                                                         |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| **API keys**             | Synced into the default project. A key synced from Daytona v0 works on both platforms unchanged.                      |
| **Container registries** | Synced into the default project.                                                                                      |
| **Snapshots**            | Synced into the default project as named images in an older format. Each image converts on first use or on request. |
| **Sandboxes**            | Not synced. Archived container sandboxes are imported one at a time as persistent sandboxes.                          |

## Get the migration summary [#get-the-migration-summary]

Get a summary of what the migration brought into the organization's default project. The summary reports whether the organization was migrated from Daytona v0 and counts the API keys, container registries, and images from Daytona v0 snapshots in the default project. Images are counted separately by whether they are converted to the current format. The summary also counts the Daytona v0 sandboxes imported so far.

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/migration/v0/summary' \
  --header 'Authorization: Bearer YOUR_API_KEY'
```

```json
{
  "from_v0": true,
  "api_keys": 3,
  "registries": 1,
  "images_to_convert": 4,
  "images_converted": 2,
  "sandboxes_imported": 5,
  "personal": false
}
```

The response has the following fields:

| **Field**            | **Description**                                                                                                                  |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `from_v0`            | `true` when the organization was migrated from Daytona v0, personal organizations included.                                     |
| `api_keys`           | The number of live API keys in the default project, both synced from Daytona v0 and created on Daytona v2.                      |
| `registries`         | The number of container registries in the default project.                                                                      |
| `images_to_convert`  | The number of images from Daytona v0 snapshots still in the older format: not converted yet, converting, or failed to convert.  |
| `images_converted`   | The number of images from Daytona v0 snapshots in the current format.                                                           |
| `sandboxes_imported` | The number of Daytona v0 sandboxes imported into the default project. A sandbox imported more than once counts once.            |
| `personal`           | `true` when the organization is a personal organization.                                                                        |

<Callout type="note" title="Notes">
- This call requires the `read:sandboxes` permission and an API key for the default project.
- Imported sandboxes that were deleted or failed are not counted.
</Callout>

</TabItem>
</Tabs>

## List Daytona v0 sandboxes [#list-daytona-v0-sandboxes]

List the organization's Daytona v0 sandboxes, one page at a time. Daytona reads the list from Daytona v0 on each request, so it reflects the current state of each sandbox. Each entry reports whether the sandbox can be imported now and, when it cannot, why. A sandbox that was already imported carries the ID of the sandbox the import created.

1. Go to [Daytona Sandboxes ↗](https://app.daytona.com/dashboard/sandboxes?version=v0)
2. Select the default project
3. Select **Daytona v0** in the version toggle

The version toggle appears only for an organization migrated from Daytona v0.

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/migration/v0/sandboxes?limit=100' \
  --header 'Authorization: Bearer YOUR_API_KEY'

# Pass next_cursor from the previous page to get the next one
curl 'https://api.daytona.com/migration/v0/sandboxes?limit=100&cursor={nextCursor}' \
  --header 'Authorization: Bearer YOUR_API_KEY'
```

| **Parameter** | **Type**  | **Description**                                                                       |
| ------------- | --------- | ------------------------------------------------------------------------------------- |
| `limit`       | `integer` | Sets the page size, from `1` to `200`. Defaults to `100`.                             |
| `cursor`      | `string`  | Resumes the list after the previous page. Pass the `next_cursor` of that page as-is. |

```json
{
  "sandboxes": [
    {
      "v0_id": "0b6c5c43-7a52-4c1f-9a42-3f0c3d7f2a11",
      "name": "data-pipeline",
      "status": "archived",
      "class": "container",
      "importable": true,
      "last_backup_at": "2026-10-14T09:21:07Z",
      "labels": { "team": "data" },
      "cpu": 2,
      "memory_gib": 4,
      "disk_gib": 10
    }
  ],
  "next_cursor": null
}
```

The response has the following fields:

| **Field**             | **Description**                                                                                     |
| --------------------- | --------------------------------------------------------------------------------------------------- |
| `sandboxes`           | The Daytona v0 sandboxes in this page.                                                              |
| `next_cursor`         | The token for the next page, or `null` on the last page.                                            |
| `v0_id`               | The sandbox ID on Daytona v0. The import takes this ID.                                             |
| `name`                | The sandbox name.                                                                                   |
| `status`              | The sandbox state on Daytona v0, for example `archived`.                                            |
| `class`               | The sandbox class on Daytona v0, for example `container`.                                           |
| `importable`          | `true` when the sandbox can be imported now.                                                        |
| `reason`              | Why the sandbox cannot be imported. Present only when `importable` is `false`.                      |
| `last_backup_at`      | When Daytona v0 last completed a backup of the sandbox, or `null`.                                  |
| `labels`              | The sandbox labels on Daytona v0.                                                                   |
| `cpu`                 | The CPU cores on Daytona v0.                                                                        |
| `memory_gib`          | The memory on Daytona v0, in GiB.                                                                   |
| `disk_gib`            | The disk size on Daytona v0, in GiB.                                                                |
| `imported_sandbox_id` | The ID of the sandbox an earlier import created. Present only while that sandbox exists.            |

The `reason` field has the following values:

| **Value**                     | **Description**                                                 |
| ----------------------------- | --------------------------------------------------------------- |
| `not_container`               | The sandbox is not a container sandbox.                         |
| `not_archived`                | The sandbox is not archived on Daytona v0.                      |
| `backup_not_completed`        | Daytona v0 has not completed a backup of the sandbox.           |
| `backup_registry_unavailable` | Daytona v0 cannot reach the registry that holds the backup.     |
| `gpu_not_supported`           | The sandbox is a GPU sandbox, which cannot be imported.         |

<Callout type="note" title="Notes">
- A page can hold fewer entries than `limit` without being the last page; only a `null` `next_cursor` ends the list.
- Daytona v0 can send a reason not listed above; Daytona passes it through unchanged.
- This call requires the `read:sandboxes` permission and an API key for the default project.
</Callout>

</TabItem>
</Tabs>

## Import a Daytona v0 sandbox [#import-a-daytona-v0-sandbox]

Import an archived Daytona v0 sandbox as a new persistent sandbox in the default project. The import registers the sandbox's last Daytona v0 backup as an image, converts the image to the current format, and creates the sandbox from it in the default project's region. The new sandbox waits in the queued state until the conversion finishes. The original Daytona v0 sandbox keeps working and is labeled with the ID of the sandbox the import created.

Importing the same sandbox again returns the existing import instead of creating another sandbox, unless you force a new import. When the sandbox an earlier import created was deleted or failed, the next import creates a new one.

1. Go to [Daytona Sandboxes ↗](https://app.daytona.com/dashboard/sandboxes?version=v0) and select **Daytona v0** in the version toggle
2. Click <Button>Import</Button> on the row of an importable sandbox
3. Click <Button>Import</Button> to confirm

<Tabs syncKey="language">
<TabItem label="API" icon="seti:json">

```bash
curl 'https://api.daytona.com/migration/v0/sandboxes/{v0Id}/import' \
  --request POST \
  --header 'Authorization: Bearer YOUR_API_KEY'

# force creates another sandbox even when a live import exists
curl 'https://api.daytona.com/migration/v0/sandboxes/{v0Id}/import' \
  --request POST \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "force": true
}'
```

| **Field** | **Type**  | **Description**                                                                              |
| --------- | --------- | -------------------------------------------------------------------------------------------- |
| `force`   | `boolean` | Creates another sandbox even when a live import of the sandbox exists. Defaults to `false`. |

```json
{
  "sandbox_id": "sbx_4kQm9TzVb2LxWp7R",
  "image_id": "img_7fJk2mQpXv9dLc3RtY",
  "status": "queued",
  "existing": false,
  "v0_labeled": true,
  "warnings": [
    "env vars not carried (sandbox secrets on Daytona v0; set them on the imported sandbox): OPENAI_API_KEY"
  ],
  "secret_env_vars": ["OPENAI_API_KEY"]
}
```

The response has the following fields:

| **Field**         | **Description**                                                                                                                                  |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `sandbox_id`      | The ID of the persistent sandbox the import created or returned.                                                                                 |
| `image_id`        | The ID of the image registered from the Daytona v0 backup.                                                                                       |
| `status`          | The sandbox status. A new import is `queued` while its image converts.                                                                           |
| `existing`        | `true` when the call returned an earlier import instead of creating a sandbox.                                                                   |
| `v0_labeled`      | `true` when Daytona v0 confirmed the label on the original sandbox. `false` means the label could not be set; repeating the call retries it.    |
| `warnings`        | The settings and values that could not be imported.                                                                                              |
| `secret_env_vars` | The names of environment variables backed by a Daytona v0 sandbox secret. The imported sandbox starts without them. Empty for an existing import. |

The call returns `201 Created` for a new import and `200 OK` when it returns an existing one.

</TabItem>
</Tabs>

The import carries the following settings from the Daytona v0 sandbox and reports every dropped setting in the warnings:

| **Setting**                                         | **Import behavior**                                                                                                                                                 |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Name**                                            | Kept when it is a valid sandbox name; otherwise the sandbox gets a generated name.                                                                                 |
| **Environment variables**                           | Kept, except reserved or invalid names, values over 64 KiB, and values that contain a NUL byte. Variables backed by a Daytona v0 sandbox secret are not carried. |
| **Labels**                                          | Kept, except labels Daytona v2 refuses and labels beyond the per-sandbox label limit. The `daytona.io/migrated-to` label is not copied.                          |
| **CPU, memory, and disk**                           | Kept, rounded up to whole units. Values above the per-sandbox limit are lowered to it.                                                                             |
| **OS user**                                         | Kept when it is a valid user name; otherwise the sandbox runs as the image's default user.                                                                         |
| **Auto-stop interval**                              | Becomes an idle timeout that stops the sandbox. An auto-stop interval of `0` disables the idle timeout.                                                            |
| **Network restrictions**                            | Become a [network policy](/docs/network-limits) that blocks all egress except the allowed CIDRs and domains. Refused entries and entries over the limit are dropped. |
| **Auto-archive and auto-delete intervals**          | Not carried. Daytona v2 has no archive state and no delete-after-stop timer.                                                                                       |
| **Volumes, sandbox ID, preview URLs, memory state** | Not carried.                                                                                                                                                        |

<Callout type="note" title="Notes">
- This call requires the `write:sandboxes` permission and an API key for the default project. An API key for another project returns `403 Forbidden` with the code `V0_MIGRATION_DEFAULT_PROJECT_ONLY`.
- Only an archived container sandbox with a completed backup can be imported. Any other sandbox returns `409 Conflict` with the code `V0_SANDBOX_NOT_IMPORTABLE`, and an unknown ID returns `404 Not Found`.
- When importing from Daytona v0 is unavailable, the call returns `503 Service Unavailable` with the code `V0_BRIDGE_UNAVAILABLE` or `V0_BACKUP_REGISTRY_UNCONFIGURED`.
- The image registered from the backup does not appear in the image list, but it can be fetched by its ID.
- The imported sandbox and its image report their origin in `imported_from`, as `{"platform": "v0", "id": "<v0Id>"}`.
</Callout>
