# Migration Extension

Lets users move their subscribers and subscriptions to another instance.

Extension name: `pub.versia:migration`

The migration extension moves an account's subscribers and the users it is subscribed to to a new account. Notes and other entities stay where they are.

## Definition

### Migration

- Type: `"pub.versia:migration/Migration"`
- Lifetime: [Transient Entity](/entities#transient-entities)

**Fields**

- `type` (`string`, required): **MUST** be `pub.versia:migration/Migration`.
- `author` (`Reference`, required): [Reference](/entities#reference) to the [User](/entities/user) who is migrating.
- `destination` (`Reference`, required): [Reference](/entities#reference) to the destination [User](/entities/user) on the new instance.

Inherited from [Entity](/entities):

- [`created_at`](/entities#entity-created-at) (`RFC3339`, required)
- [`extensions`](/entities#entity-extensions) (`Extensions`)

```json title="Example Entity"
{
    "type": "pub.versia:migration/Migration",
    "author": "example.com:034syrr1jc002",
    "created_at": "2021-01-01T00:00:00Z",
    "destination": "other.example:0338qkp85w001"
}
```

### User Extensions

The following extensions to [User](/entities/user) are used by the migration extension:

- Extension ID: `pub.versia:migration`
- Extends: [User](/entities/user)

**Fields**

- `previous` (`Reference`): If this user is migrating or has migrated from another instance, this property **MUST** be a [Reference](/entities#reference) to the user on the previous instance.
- `destination` (`Reference`): If this user has migrated to another instance, this property **MUST** be a [Reference](/entities#reference) to the user on the new instance.

```jsonc title="Example"
{
    // ...
    "type": "User",
    // ...
    "extensions": {
        "pub.versia:migration": {
            "previous": "old.example:034syrr1jc002"
            // "destination": "new.example:0338qkp85w001"
        }
    }
}
```

## Behavior

Migration happens in three steps:

### Prepare the New Account

The user creates an account on the new instance, and sets its `previous` field to a [Reference](/entities#reference) to the old account.

### Request Migration

The user requests migration from the old instance. The old instance checks that the new account's `previous` field names the old account, and sends a Migration entity.

It **MUST** [deliver](/federation#delivery) the Migration to the instances hosting a subscriber of the old account or a user it is subscribed to, and to the new account's instance. It **MAY** also deliver it to others.

A receiver **MUST** fetch the `destination` account, and **MUST** ignore the Migration if that account's `previous` field does not name the `author`.

Subscriptions then move through normal [Subscribes](/entities/subscribe):

- An instance hosting a subscriber of the old account **MUST** send a Subscribe to the new account for each of them, and drop their subscription to the old account.
- The new account's instance **SHOULD** accept these Subscribes automatically, even if the account has `manually_approves_subscribers` set.
- The new account's instance **MUST** send a Subscribe to each account in the old account's `subscriptions` collection. The target's usual rules apply, so one who manually approves subscribers still decides.

### Complete Migration

The old instance sets the `destination` field of the old account to a [Reference](/entities#reference) to the new account, and disables the old account.

It **SHOULD** keep serving the old account and its `subscribers` and `subscriptions` collections for at least 30 days, so that other instances can finish moving.

A [domain handle](/extensions/domain-handles#moving-instances) moves when the user changes its DNS record or file to name the new account.
