# Move existing mail into a mailbox

> Copy mail into a mailbox from another server over IMAP, from Gmail or Microsoft 365, or from an mbox, eml, zip or cPanel backup file.

Source: https://www.coritan.com/docs/mail/mail-hosting/move-mail-in/

In the dashboard:

- /dashboard/mail/…/mailboxes: https://www.coritan.com/dashboard/mail

An *import* copies mail into a mailbox from another mail server or from a file. It runs on our side, so it carries on after you close the page. Messages keep their folders, their read and flagged state and their original dates, and nothing changes on the other server.

The mailbox's own user can start the same imports from webmail; see [Import mail into webmail](/docs/mail/webmail/import/).

## Before you begin

- A mailbox to copy the mail into, with room for it: an import pauses when the mailbox is full. To make room, [change the mailbox's quota](/docs/mail/mail-hosting/mailboxes/#change-a-mailbox-s-quota).
- For another server: the address and password of the old mailbox, and IMAP turned on there. Many providers want an *app password* made in their own settings rather than the account password; the hint under **Provider** says what each one needs.
- For a file: a copy of the mail as an mbox file, a single `.eml` message, a zip or tar of mail files, or a cPanel backup.

## Import from another server

1. In the dashboard, go to [**Email**](https://www.coritan.com/dashboard/mail), open the Mail Hosting service, then the **Mailboxes** tab.
2. Open the menu at the end of the mailbox's row and select **Bring mail in…**.
3. In **Provider**, choose where the mail is now, such as `Yahoo Mail` or `iCloud Mail`. For a server that is not listed, or a cPanel host, choose `Another IMAP server` or `cPanel`, then enter its name in **Server**.
4. In **Username**, enter the old mailbox's sign-in name, usually its full address. In **Password**, enter its password or app password.
5. To copy the old Trash or Spam folders too, turn on **Also bring Trash** or **Also bring Spam**.
6. Select **Import from the server**.

We sign in to the old server first, so a wrong password shows at once. The import then appears in the list under the form, and the list updates by itself while it runs.

The server must offer IMAP over TLS on port `993`. We use the password only for this import and forget it when the import ends.

## Import from Gmail or Microsoft 365 by signing in

When the **Provider** list offers **Gmail: sign in with Google** or **Microsoft 365 or Outlook.com: sign in with Microsoft**, you can sign in on the provider's own page instead of giving us a password.

1. In **Bring mail in**, choose one of those two in **Provider**.
2. Optionally, turn on **Also bring Trash** or **Also bring Spam**.
3. Select the button that continues to the provider, and sign in there.

You come back to the **Mailboxes** tab with the message `Signed in. The import has started, and goes on with this page closed.` If the sign-in did not work, the message says why.

Microsoft 365 no longer accepts passwords over IMAP, so signing in is the only way to import from it. For Gmail without signing in, choose `Gmail with an app password` and make an app password in your Google account.

## Import from a file

1. In **Bring mail in**, select a file in **Or a file**.
2. Select **Upload and import**. The button shows how much has uploaded; keep the page open until it finishes.

When the upload ends, the import appears in the list. We tell what the file is from its name and first bytes:

| File | What we import |
| --- | --- |
| mbox (`.mbox`, `.mbx`), including a Google Takeout export | Every message in it |
| `.eml` | The one message |
| zip or tar of mail files | Every message, keeping its folders |
| cPanel backup (`backup-…` or `cpmove-…` archive) | The mailbox in the backup with the same address as this one |

Mail from a file that has no folders, such as an mbox or an `.eml`, goes into a folder named `Imported`. A Google Takeout mbox is the exception: its messages go where their Gmail labels say, as they would from Gmail itself.

## Where the mail goes

- The old Inbox, Sent, Drafts and Archive go into the mailbox's own folders of the same kind, and Trash and Spam too when you turned them on. We recognise them by the flags servers put on them, or by their usual names in several languages.
- Any other folder is made in the mailbox with the same name and path.
- From Gmail, each message is copied once and placed in every folder its labels name. Starred and Important become flags, and a message with no label goes to Archive.
- We leave out messages marked deleted, messages larger than 50 MB, and messages already in the mailbox from an earlier import.

## Follow an import

Each import in the list shows its source, a status, and its counts: how many messages were imported, how many were **already there**, and how many were **left out**.

| Status | Meaning |
| --- | --- |
| **Waiting** | Queued to start. |
| **Importing** | Copying mail now. |
| **Paused** | Stopped for now: you paused it, the mailbox is full, or an error interrupted it. **Resume** goes on from where it stopped. |
| **Done** | Every message has been copied. |
| **Stopped** | It failed. The row says why, for example the old server refused the password or the file could not be read. |
| **Cancelled** | You cancelled it. |

When the old server does not answer, an import tries again on its own, up to five times, a few minutes apart. When Gmail stops handing over mail for the day, the import tries again every six hours until it finishes.

## Pause, resume or cancel an import

- To pause a waiting or running import, select **Pause** on its row.
- To go on with a paused import, select **Resume**.
- To stop one for good, select **Cancel…**, then **Cancel import**. The mail already copied stays in the mailbox, and we forget the password or delete the file.

Running the same import again is safe: messages already copied count as **already there** and are not copied twice.

## Troubleshooting

`… refused that username and password.`
: The old server did not accept the sign-in. Check the username, and whether the provider wants an app password or needs IMAP turned on first. The hint under **Provider** says which.

`… did not answer`
: We could not reach the server on port `993`. Check the name in **Server**, and that the server offers IMAP over TLS.

`3 imports are under way into this mailbox; wait for one to end`
: A mailbox takes three imports at a time, counting waiting and paused ones. Wait for one to finish, or cancel one.

`Too many requests for this action. Please wait and try again.`
: A mailbox takes up to 20 import attempts a day, counting those the old server refused. Try again later.

`That file is not an mbox, an .eml, a zip or a tar of mail, or a cPanel backup`
: We could not tell what the file is. Check that it is one of those, with its usual file name ending.

`Imports take files up to … MB`
: The file is larger than an import takes. Split it into smaller files, or import from the server instead.

`This backup holds no mailbox …`
: The cPanel backup has no mailbox with this mailbox's address. The message lists the mailboxes it does hold. Import into a mailbox with one of those addresses, or choose the one you want with the API's `cpanel_mailbox` field.

The import is **Paused** and the mailbox is full
: The import stops when the mailbox reaches its quota. [Raise the quota](/docs/mail/mail-hosting/mailboxes/#change-a-mailbox-s-quota) or delete mail, then select **Resume**.

## Related

- [Create and manage mailboxes](/docs/mail/mail-hosting/mailboxes/)
- [Add a domain to Mail Hosting](/docs/mail/mail-hosting/add-a-domain/)
- [Import mail into webmail](/docs/mail/webmail/import/)

## With the API

All the paths below sit under `/client/mail/{service_id}/mailboxes/{account_id}/imports`.

Start an import from another server:

```bash
curl -X POST https://api.coritan.com/api/v1/client/mail/4812/mailboxes/5120/imports \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"preset": "other", "host": "imap.example.net", "username": "alex@example.net", "password": "old-mailbox-password", "since": "2024-01-01"}'
```

The body takes these fields:

`preset`
: The provider, as an `id` from the `presets` list in `GET .../imports`: `cpanel`, `gmail`, `yahoo`, `icloud`, `zoho`, `fastmail`, `aol`, `gmx`, `yandex` or `other`. Defaults to `other`.

`host`
: The server's name, for `cpanel` and `other`. A preset with its own host ignores it.

`username`, `password`
: The old mailbox's sign-in, 1–254 and 1–512 characters.

`folders`
: Optional, up to 200 folder paths to import. Leave it out to import every folder.

`since`, `until`
: Optional dates such as `2024-01-01`. We leave out messages dated outside them.

`trash`, `spam`
: Optional, `false` by default. Whether to import the Trash and Spam folders.

The answer is `201` with the import:

```json
{
  "id": 77,
  "kind": "imap",
  "status": "queued",
  "source": {"host": "imap.example.net", "port": 993, "username": "alex@example.net", "preset": "other"},
  "options": {"trash": false, "spam": false, "since": "2024-01-01"},
  "imported": 0,
  "duplicates": 0,
  "skipped": 0,
  "failed": 0,
  "total": null,
  "error": null,
  "started_by": "the Mail Hosting panel",
  "folders_done": 0,
  "folders": 0,
  "created_at": "2026-09-16T11:20:05.201344+00:00",
  "started_at": null,
  "finished_at": null
}
```

Upload a file as `multipart/form-data`:

```bash
curl -X POST https://api.coritan.com/api/v1/client/mail/4812/mailboxes/5120/imports/upload \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -F "file=@backup-example.com.tar.gz" \
  -F "kind=cpanel" \
  -F "cpanel_mailbox=alex@example.com"
```

The form takes `file`, and optionally `kind` (`cpanel` or `eml`, when the file's name does not say), `folder` (where mail from a file with no folders goes, `Imported` by default), `cpanel_mailbox` (which mailbox of a cPanel backup to import; this mailbox's address by default), `trash` and `spam`. The answer is `201` with the import.

The other operations:

| Operation | Body | Answer |
| --- | --- | --- |
| `GET .../imports` | | `{"items": [...], "presets": [...], "max_upload_mb": ..., "oauth": {"google": ..., "microsoft": ...}}`: the last 20 imports, newest first, the providers, the largest file an upload takes in MB, and which sign-ins are available |
| `POST .../imports/oauth` | `{"provider": "google", "return_path": "/dashboard/mail/4812/mailboxes"}`, with optional `since`, `until`, `trash` and `spam` | `{"url": "..."}`: send the browser there to sign in. It comes back to `return_path` on the host the request went to, which must be `www.coritan.com`, so send this one to `https://www.coritan.com/api/v1`. |
| `POST .../imports/{import_id}/pause` | | The import, `paused` |
| `POST .../imports/{import_id}/resume` | | The import, `queued` |
| `POST .../imports/{import_id}/cancel` | | The import, `cancelled` |

A refused request answers with a `detail` object that holds a `code` and a `message`:

| Status | `code` | When |
| --- | --- | --- |
| `422` | `source_refused`, `source_unreachable` | The old server refused the sign-in or did not answer |
| `422` | `unknown_preset`, `source_incomplete` | The `preset` is not one of the list, or the server, username or password is missing |
| `422` | `unknown_file`, `empty_file` | We could not tell what the file is, or it is empty |
| `422` | `oauth_unavailable` | Signing in to that provider is not available |
| `422` | `oauth_origin` | A sign-in was started through a host other than `www.coritan.com`, such as `api.coritan.com` |
| `409` | `imports_busy` | Three imports are under way into the mailbox |
| `409` | `import_state` | The import's status does not allow the action, such as resuming one that is running |
| `413` | `file_too_large` | The file is larger than `max_upload_mb` |

An `import_id` that is not on the mailbox answers `404` `Import not found`, and the 21st attempt in a day answers `429`.

## API

- `GET /api/v1/client/mail/{service_id}/mailboxes/{account_id}/imports`: Mailbox imports (https://www.coritan.com/docs/api/reference/client/mail/mail-mailboxes/#op-get-api-v1-client-mail-service-id-mailboxes-account-id-imports)
- `POST /api/v1/client/mail/{service_id}/mailboxes/{account_id}/imports`: Mailbox import start (https://www.coritan.com/docs/api/reference/client/mail/mail-mailboxes/#op-post-api-v1-client-mail-service-id-mailboxes-account-id-imports)
- `POST /api/v1/client/mail/{service_id}/mailboxes/{account_id}/imports/oauth`: Mailbox import sign in (https://www.coritan.com/docs/api/reference/client/mail/mail-mailboxes/#op-post-api-v1-client-mail-service-id-mailboxes-account-id-imports-oauth)
- `POST /api/v1/client/mail/{service_id}/mailboxes/{account_id}/imports/upload`: Mailbox import upload (https://www.coritan.com/docs/api/reference/client/mail/mail-mailboxes/#op-post-api-v1-client-mail-service-id-mailboxes-account-id-imports-upload)
- `POST /api/v1/client/mail/{service_id}/mailboxes/{account_id}/imports/{import_id}/{action}`: Mailbox import steer (https://www.coritan.com/docs/api/reference/client/mail/mail-mailboxes/#op-post-api-v1-client-mail-service-id-mailboxes-account-id-imports-import-id-action)
