---
title: "Finish a migration"
method: POST
path: "/customers/{id}/domains/{domain}/migrations/{migrationId}/finish"
tags: ["Partners"]
---

# Finish a migration

`POST /customers/{id}/domains/{domain}/migrations/{migrationId}/finish`

## Request

- Base URL: `https://faivelo.com/api/partner`
- URL: `https://faivelo.com/api/partner/customers/{id}/domains/{domain}/migrations/{migrationId}/finish`
- Auth: HTTP bearer

One last sync, then every source password is deleted from Faivelo. Do it after the domain's MX record points at Faivelo. Requires `partner:write`.

## Path parameters

- `id` string, required
- `domain` string, required
- `migrationId` string, required

## Response `200`

The migration

- object
  - `success` boolean
  - `data` PartnerMigration
    - `id` string
    - `domain` string
    - `source` PartnerMigrationSource
      - `host` string, required
      - `port` integer
      - `tls` boolean
    - `status` 'PENDING' | 'RUNNING' | 'COMPLETED' | 'PARTIAL' | 'FAILED'
    - `phase` 'copying' | 'idle' | 'finishing' | 'finished': copying: a pass is queued or running; idle: waiting for you to sync again or finish; finishing: the last pass is queued; finished: the source credentials are deleted
    - `credentialsHeld` boolean: True until the domain is finished: the source passwords are still stored (encrypted) so sync works
    - `createdAt` string, date-time
    - `startedAt` string, date-time, nullable
    - `completedAt` string, date-time, nullable
    - `finishRequestedAt` string, date-time, nullable: When finish was requested; the last pass is running until finishedAt
    - `finishedAt` string, date-time, nullable
    - `mailboxes` PartnerMigrationMailbox[]
      - `sourceEmail` string
      - `destAddress` string
      - `status` 'PENDING' | 'RUNNING' | 'COMPLETED' | 'PARTIAL' | 'FAILED'
      - `totalMessages` integer
      - `copiedMessages` integer
      - `failedMessages` integer
      - `bytesCopied` integer
      - `lastSyncedAt` string, date-time, nullable
      - `syncPending` boolean: Another pass is queued or running for this mailbox
      - `error` string, nullable
    - `totals` object
      - `mailboxes` integer
      - `running` integer
      - `completed` integer
      - `failed` integer
      - `totalMessages` integer
      - `copiedMessages` integer: Accumulates across sync passes, so it can exceed totalMessages
      - `failedMessages` integer
      - `bytesCopied` integer
      - `syncPending` integer: Mailboxes with a pass queued or running
      - `syncedUpTo` string, date-time, nullable: The domain is synced up to here: the oldest last pass among its mailboxes

## Other responses

- `401`: Missing or invalid API key, or not a partner key
- `403`: The key lacks the required scope, or provisioning is refused (partner paused, customer cap reached)
- `404`: Not found, including any customer that is not yours
- `409`: Refused with a `code`: FINISHED (already finished) or NOT_HELD
- `429`: Rate limit exceeded

---

[API](https://skmtc.dev/faivelo/apis/faivelo-api.md) · [All operations](https://skmtc.dev/faivelo/apis/faivelo-api/llms.txt) · [OpenAPI document](https://skmtc.dev/faivelo/apis/faivelo-api/revisions/a7413ddea5d1?raw)
