# How Managed Transfers works
URL: https://musicapi.com/docs/managed-transfers/how-it-works.md

> The hosted, white-label transfer wizard, its sessions, the library snapshots, matching, and the rule of one transfer at a time per person.

Product: MusicAPI Managed Transfers. Section: Managed Transfers.

MusicAPI Managed Transfers moves a user's library from the service they use now into your service. It is a hosted, white-label flow: your users open a page, connect both services, pick what to move and watch it happen. You write no wizard, no matching and no retry logic. Your backend follows the result through webhooks.

## The entry URL

```url
https://app.musicapi.com/{slug}/transfer
```

With a [custom domain](https://musicapi.com/docs/managed-transfers/turn-on-and-brand.md#custom-domain), the same path answers on your host: `https://transfer.example.com/{slug}/transfer`.

## The wizard

1. **Choose a source**

   The user picks the service they leave. The list holds the music integrations that are on in your account, minus your destination.
2. **Connect both accounts**

   The user signs in to the source, then to your destination service, through the [hosted sign-in](https://musicapi.com/docs/connect-users/how-sign-in-works.md). A [pre-authorized session](https://musicapi.com/docs/managed-transfers/preauthorized-sessions.md) skips the destination sign-in.
3. **Pick the content**

   Playlists, followed playlists, liked tracks, albums and artists, as far as you allow them for that source and the services support them.
4. **Confirm**

   The user reviews the selection and starts the transfer. For a playlist that already exists on the destination, the user picks how to handle it.
5. **Progress and results**

   A live progress page, then a results page with the match rate, the unmatched items and a CSV export. We do not email your users unless you turn on [transfer emails](https://musicapi.com/docs/managed-transfers/turn-on-and-brand.md#transfer-emails).

## Sessions

- Every page of the wizard is anonymous. The user needs no account with you or with us.
- A session lives in the user's browser for **24 hours**.
- After the transfer starts, the browser also keeps a read-only key to it. The user can reload the progress and results pages for **30 days**.
- The browser never holds your API keys or the user's service tokens.

## Library snapshots

When a user connects an account, MusicAPI reads the library once and keeps a snapshot. Every wizard screen reads that snapshot, so picking content is fast and costs no extra calls to the service. A **Refresh** in the wizard reads the library again. A transfer reads the source as it was in the snapshot that the user picked from.

## Matching

For each source item, MusicAPI searches the destination: first by ISRC where the destination supports it, then by name, artists and album. A candidate must score at least the match threshold of your account (80 out of 100 by default). Below it, the item is unmatched with the reason `lowConfidence`, and the closest candidate is reported as the best guess.

Unmatched items and their reasons: [Transfer results and unmatched items](https://musicapi.com/docs/managed-transfers/results-and-unmatched.md).

## One transfer at a time per person

Transfers of one person run one after the other, never side by side. A second transfer waits until the first one ends, then starts by itself.

When a music service asks MusicAPI to slow down, the transfer waits and continues by itself. When a service keeps refusing for too long, the transfer fails with `errorType: "rateLimited"` and `failureReason: "rateLimited"`.

## Transfer states

| Status                           | Meaning                                                                                                                                                                                                                                     |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `created`, `fetching`, `running` | The transfer reads the source and writes the destination.                                                                                                                                                                                   |
| `paused`                         | The transfer is paused.                                                                                                                                                                                                                     |
| `waitingForReauth`               | One account needs a new sign-in. Nothing is lost. The transfer continues after the user signs in again, or after your backend [pushes a new token](https://musicapi.com/docs/managed-transfers/preauthorized-sessions.md#push-a-new-token). |
| `completed`                      | Every item reached the destination or was already there.                                                                                                                                                                                    |
| `completedWithErrors`            | The transfer ended, and some items did not match or failed.                                                                                                                                                                                 |
| `failed`                         | The transfer stopped and cannot continue.                                                                                                                                                                                                   |
| `cancelled`                      | The transfer was cancelled.                                                                                                                                                                                                                 |

## What you see

- **Transfers** in the dashboard: every transfer with its status and match rate, with a CSV export.
- **Analytics → Funnel**: where users drop out, from the first page view to a finished transfer.
- **Analytics → Reliability**: error rates per service, and the [alert rules](https://musicapi.com/docs/webhooks/alert-rules.md).
- [Webhooks](https://musicapi.com/docs/webhooks/set-up-and-verify.md) for your backend, and the [Match Results API](https://musicapi.com/docs/managed-transfers/results-and-unmatched.md) for the unmatched items.

> **Do not poll:** Webhooks tell your backend what happened. Fetch the unmatched items after `match.report_ready`, or once a day with the bulk endpoint. Do not call the API in a loop to follow a running transfer.
