---
title: "client.ConnectedMailboxes"
description: "Every method in this namespace: its signature, its parameters, what it returns and an example."
url: "https://openemail.uk/docs/csharp/reference/connected-mailboxes"
area: "C#"
category: "Reference"
---

# client.ConnectedMailboxes

Every method in this namespace: its signature, its parameters, what it returns and an example.

## Methods

Mailboxes that stay at Gmail, Yahoo, iCloud or another provider and are worked from Nextmail: find their mail servers, connect one with an app password, see whether it syncs, pause, resume or rename it, give it a new password, sync it now and disconnect it. New mail is copied in, what is done to it here goes back to the provider, and mail written as its address is sent through the provider.

### `ConnectedMailboxes.ListAsync`

List the connected mailboxes

```csharp
Task<IReadOnlyList<JsonObject>> ListAsync(
    string? apiKey = null,
    CancellationToken cancellationToken = default)
```

Returns every mailbox connected to the workspace in one list, newest first. The list comes whole and is never paged. A connected mailbox stays at its provider, such as Gmail or Yahoo, and is worked from Nextmail: its new mail is copied in, what is done to it here goes back to the provider, and mail written as its address is sent through the provider.

`status` is `active` while it syncs and sends, `paused` while a person stopped it, `needs-sign-in` when the provider stopped accepting its password, and `failing` when the last five syncs failed and it keeps trying less often.

Scopes: `threads:read`.

**Parameters**

- `apiKey` (`string?`): Overrides the client's API key for this call only.
- `cancellationToken` (`CancellationToken`): Cancels the request.

**Returns**

A list of `JsonObject` items. Each item has `id`, `addressId`, `email`, `label`, `provider`, `method`, `status`, `pauseReason`, `lastError`, `lastSyncedAt`, `createdAt`, `connectedBy`, `username`, `imap`, `smtp` and `historyImportId`.

**Example**

```csharp
var mailboxes = await client.ConnectedMailboxes.ListAsync();

foreach (var mailbox in mailboxes)
{
    Console.WriteLine($"{mailbox["email"]} {mailbox["status"]} {mailbox["lastSyncedAt"]}");
}
```

**Notes**

- A key or an app limited to particular addresses sees only the mailboxes of those addresses.
- `lastError` is what the mail server said the last time something went wrong, and null while nothing is wrong.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /connected-mailboxes`](https://openemail.uk/docs/api/reference/connected-mailboxes#get-connected-mailboxes); TypeScript [`nextmail.connectedMailboxes.list()`](https://openemail.uk/docs/sdk/reference/connected-mailboxes#list); Python [`connected_mailboxes.list()`](https://openemail.uk/docs/python/reference/connected-mailboxes#list); Ruby [`connected_mailboxes.list`](https://openemail.uk/docs/ruby/reference/connected-mailboxes#list); PHP [`connectedMailboxes->list`](https://openemail.uk/docs/php/reference/connected-mailboxes#list); Go [`ConnectedMailboxes.List`](https://openemail.uk/docs/go/reference/connected-mailboxes#list); Java [`connectedMailboxes().list`](https://openemail.uk/docs/java/reference/connected-mailboxes#list); CLI [`openemail connected-mailboxes list`](https://openemail.uk/docs/cli/reference/connected-mailboxes#connected-mailboxes-list).

### `ConnectedMailboxes.GetAsync`

Read one connected mailbox by id

```csharp
Task<JsonObject> GetAsync(
    string id,
    string? apiKey = null,
    CancellationToken cancellationToken = default)
```

Looks up one connected mailbox and returns it in the same shape as a row of `ListAsync`: whether it is syncing, when it last finished, and what went wrong if it did not.

Scopes: `threads:read`.

**Parameters**

- `id` (`string`, required): Connected mailbox id such as `cmb_5c1e9a7b3d2f48e6a0b4c7d1`, as `ListAsync` returns it.
- `apiKey` (`string?`): Overrides the client's API key for this call only.
- `cancellationToken` (`CancellationToken`): Cancels the request.

**Returns**

A `JsonObject` with `id`, `addressId`, `email`, `label`, `provider`, `method`, `status`, `pauseReason`, `lastError`, `lastSyncedAt`, `createdAt`, `connectedBy`, `username`, `imap`, `smtp` and `historyImportId`.

**Example**

```csharp
using Nextmail.Constants;

var mailbox = await client.ConnectedMailboxes.GetAsync("cmb_5c1e9a7b3d2f48e6a0b4c7d1");

if ((string?)mailbox["status"] == ConnectedMailboxStatuses.NeedsSignIn)
{
    Console.WriteLine($"{mailbox["email"]} needs a new app password: {mailbox["lastError"]}");
}
```

**Notes**

- A missing mailbox, or one whose address the caller cannot reach, throws an `NextmailApiException` whose `IsNotFound` is true and whose `Code` is `connected_mailbox_not_found`.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /connected-mailboxes/{id}`](https://openemail.uk/docs/api/reference/connected-mailboxes#get-connected-mailboxes-id); TypeScript [`nextmail.connectedMailboxes.get()`](https://openemail.uk/docs/sdk/reference/connected-mailboxes#get); Python [`connected_mailboxes.get()`](https://openemail.uk/docs/python/reference/connected-mailboxes#get); Ruby [`connected_mailboxes.get`](https://openemail.uk/docs/ruby/reference/connected-mailboxes#get); PHP [`connectedMailboxes->get`](https://openemail.uk/docs/php/reference/connected-mailboxes#get); Go [`ConnectedMailboxes.Get`](https://openemail.uk/docs/go/reference/connected-mailboxes#get); Java [`connectedMailboxes().get`](https://openemail.uk/docs/java/reference/connected-mailboxes#get); CLI [`openemail connected-mailboxes get`](https://openemail.uk/docs/cli/reference/connected-mailboxes#connected-mailboxes-get).

### `ConnectedMailboxes.DiscoverAsync`

Find the mail servers for a mailbox

```csharp
Task<JsonObject> DiscoverAsync(
    string email,
    string? apiKey = null,
    CancellationToken cancellationToken = default)
```

Looks up where the mailbox behind an address lives and what it signs in with, so the right password can be asked for before `ConnectAsync`. Nothing is stored and no sign-in is attempted.

`signIn` is `app-password` for Gmail, Yahoo, iCloud and the other providers that want one, `password` where the everyday password works, and `microsoft` for Outlook.com and Microsoft 365, which only the Microsoft sign-in in the app can connect. `imap` is null when nothing was found: pass `host` to `ConnectAsync`. `smtp` is null when the outgoing server is found while connecting, or can be passed as `smtpHost`.

Scopes: `domains:write`.

**Parameters**

- `email` (`string`, required): The address of the mailbox.
- `apiKey` (`string?`): Overrides the client's API key for this call only.
- `cancellationToken` (`CancellationToken`): Cancels the request.

**Returns**

A `JsonObject` with `email`, `provider`, `signIn`, `imap` and `smtp`.

**Example**

```csharp
using Nextmail.Constants;

var settings = await client.ConnectedMailboxes.DiscoverAsync("ada@gmail.com");

if ((string?)settings["signIn"] == MailboxSignIns.AppPassword)
{
    Console.WriteLine($"Make an app password at {settings["provider"]}");
}

Console.WriteLine(settings["imap"] is null ? "Ask for the IMAP host" : $"Mail is read from {settings["imap"]?["host"]}");
```

**Notes**

- Something that is not an email address is a 400 `mailbox_address_invalid`.
- Too many lookups in an hour is a 429 `mailbox_checks_limited`.
- A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client `MaxRetries`, and on a 429 only when it carries a `Retry-After` of a minute or less.

Also available in: API [`GET /connected-mailboxes/settings`](https://openemail.uk/docs/api/reference/connected-mailboxes#get-connected-mailboxes-settings); TypeScript [`nextmail.connectedMailboxes.discover()`](https://openemail.uk/docs/sdk/reference/connected-mailboxes#discover); Python [`connected_mailboxes.discover()`](https://openemail.uk/docs/python/reference/connected-mailboxes#discover); Ruby [`connected_mailboxes.discover`](https://openemail.uk/docs/ruby/reference/connected-mailboxes#discover); PHP [`connectedMailboxes->discover`](https://openemail.uk/docs/php/reference/connected-mailboxes#discover); Go [`ConnectedMailboxes.Discover`](https://openemail.uk/docs/go/reference/connected-mailboxes#discover); Java [`connectedMailboxes().discover`](https://openemail.uk/docs/java/reference/connected-mailboxes#discover); CLI [`openemail connected-mailboxes discover`](https://openemail.uk/docs/cli/reference/connected-mailboxes#connected-mailboxes-discover).

### `ConnectedMailboxes.ConnectAsync`

Connect a mailbox at another provider

```csharp
Task<JsonObject> ConnectAsync(
    IReadOnlyDictionary<string, object?> body,
    string? apiKey = null,
    CancellationToken cancellationToken = default)
```

Connects a mailbox that stays at Gmail, Yahoo, iCloud or another provider, so its address becomes an address of the workspace while its mail stays where it is. It signs in to the incoming and the outgoing server with the password, keeps the password sealed, adds the address and starts copying new mail in within a minute.

From then on read, starred, archived, spam and deleted go back to the provider, and mail written as the address goes out through the provider, so it lands in its Sent folder too. With `importHistory` set to true it also starts an import of the mail already in the mailbox, which `Imports.GetAsync` follows by `historyImportId`.

Most providers want an app password, made in the account's security settings, not the everyday password. Leave `host` and `smtpHost` out to have the servers found from the address, as `DiscoverAsync` shows.

Scopes: `domains:write`.

**Parameters**

- `email` (`string`, required): The address of the mailbox, such as `you@gmail.com`.
- `password` (`string`, required): The app password of the mailbox, or its password where the provider has no app passwords.
- `host` (`string`): The IMAP server. Left out, it is looked up from the address.
- `port` (`int`): The IMAP port: 993 with TLS, or 143 with STARTTLS.
- `security` (`string`): How the IMAP connection is encrypted: `tls` or `starttls`.
- `username` (`string`): The name to sign in with, when it is not the address.
- `smtpHost` (`string`): The SMTP server mail is sent through. Left out, it is found.
- `smtpPort` (`int`): The SMTP port: 465 with TLS, or 587 with STARTTLS.
- `smtpSecurity` (`string`): How the SMTP connection is encrypted: `tls` or `starttls`.
- `label` (`string`): A name for the address, shown beside it in the app, up to 120 characters.
- `importHistory` (`bool`): Whether to copy the mail already in the mailbox as well. Left out, only mail that arrives from now on comes in.
- `apiKey` (`string?`): Overrides the client's API key for this call only.
- `cancellationToken` (`CancellationToken`): Cancels the request.

**Returns**

A `JsonObject` with a new `id`, the `addressId` the mailbox appears as, and `status` `active`.

**Example**

```csharp
var mailbox = await client.ConnectedMailboxes.ConnectAsync(new Body
{
    ["email"] = "ada@gmail.com",
    ["password"] = Environment.GetEnvironmentVariable("GMAIL_APP_PASSWORD"),
    ["label"] = "Ada (Gmail)",
    ["importHistory"] = true,
});

Console.WriteLine($"{mailbox["id"]} {mailbox["addressId"]} {mailbox["status"]}");
```

**Notes**

- Mail from a connected address is sent through the provider, never through Nextmail's servers, and only to people. Broadcasts, automations, sign-up forms and `Emails.SendAsync` with an API key refuse it as the sender.
- A wrong password is a 400 `mailbox_login_failed`, and an outgoing server that refuses it a 400 `connected_mailbox_send_sign_in_failed`. No server found is a 400 `mailbox_settings_unknown` or `connected_mailbox_send_server_unknown`. An Outlook.com or Microsoft 365 mailbox is a 400 `mailbox_uses_microsoft`: connect it with the Microsoft sign-in in the app, and manage it from here after that.
- An address whose mail already comes to Nextmail is a 400 `connected_mailbox_domain_hosted`. A mailbox already connected here is a 409 `connected_mailbox_already_connected`, and one connected to another workspace a 409 `connected_mailbox_connected_elsewhere`.
- The address counts toward the addresses of the plan, and a full plan is a 422 `workspace_limit_reached`. A key or an app limited to particular addresses or domains is refused with 422 `capability_unsupported`.
- Each person may make 10 sign-in attempts an hour across this call, `UpdateAsync` with a password and the `Imports` calls that sign in to a mailbox, and more is a 429 `mailbox_checks_limited`.
- Not retried automatically: a retry after a lost response answers 409 `connected_mailbox_already_connected`, which then means the first call went through.

Also available in: API [`POST /connected-mailboxes`](https://openemail.uk/docs/api/reference/connected-mailboxes#post-connected-mailboxes); TypeScript [`nextmail.connectedMailboxes.connect()`](https://openemail.uk/docs/sdk/reference/connected-mailboxes#connect); Python [`connected_mailboxes.connect()`](https://openemail.uk/docs/python/reference/connected-mailboxes#connect); Ruby [`connected_mailboxes.connect`](https://openemail.uk/docs/ruby/reference/connected-mailboxes#connect); PHP [`connectedMailboxes->connect`](https://openemail.uk/docs/php/reference/connected-mailboxes#connect); Go [`ConnectedMailboxes.Connect`](https://openemail.uk/docs/go/reference/connected-mailboxes#connect); Java [`connectedMailboxes().connect`](https://openemail.uk/docs/java/reference/connected-mailboxes#connect); CLI [`openemail connected-mailboxes connect`](https://openemail.uk/docs/cli/reference/connected-mailboxes#connected-mailboxes-connect).

### `ConnectedMailboxes.UpdateAsync`

Pause, resume or rename a connected mailbox, or give it a new password

```csharp
Task<JsonObject> UpdateAsync(
    string id,
    IReadOnlyDictionary<string, object?> patch,
    string? apiKey = null,
    CancellationToken cancellationToken = default)
```

Changes a connected mailbox and returns it as it is now. Send only what changes: a field left out stays as it is.

`paused` set to true stops syncing and sending through the mailbox, and `paused` set to false starts both again. The mail already copied in stays either way. `password` gives it a new app password after the provider stopped accepting the old one: it is checked against both servers before it is kept, and a mailbox that needed signing in starts syncing again. `label` renames its address, and null clears the name.

Scopes: `domains:write`.

**Parameters**

- `id` (`string`, required): Connected mailbox id such as `cmb_5c1e9a7b3d2f48e6a0b4c7d1`, as `ListAsync` returns it.
- `paused` (`bool`): True pauses the mailbox and false resumes it. Left out, it stays as it is.
- `password` (`string`): A new app password. Left out, the password stays.
- `label` (`string`): A name for the address, up to 120 characters, or null to clear it. Left out, the name stays.
- `apiKey` (`string?`): Overrides the client's API key for this call only.
- `cancellationToken` (`CancellationToken`): Cancels the request.

**Returns**

A `JsonObject` with the unchanged `id`, and `status`, `pauseReason` and `label` as they are now.

**Example**

```csharp
var mailbox = await client.ConnectedMailboxes.UpdateAsync("cmb_5c1e9a7b3d2f48e6a0b4c7d1", new Body
{
    ["password"] = Environment.GetEnvironmentVariable("GMAIL_APP_PASSWORD"),
});

Console.WriteLine(mailbox["status"]);
```

**Notes**

- A mailbox that needs signing in cannot be paused or resumed until it has a new password, or until a `microsoft` one is signed in again in the app.
- A password the mail server refuses is a 400 `mailbox_login_failed` or `connected_mailbox_send_sign_in_failed`, and the old one stays. A `microsoft` mailbox has no password to change, which is a 400 `connected_mailbox_no_password`: it signs in again in the app. A missing mailbox is a 404 `connected_mailbox_not_found`.
- A value of the wrong type or length is 422 `invalid_parameter`, and a key the patch does not take 422 `unknown_parameter`.
- Not retried automatically. Read it with `GetAsync` before you try again.

Also available in: API [`PATCH /connected-mailboxes/{id}`](https://openemail.uk/docs/api/reference/connected-mailboxes#patch-connected-mailboxes-id); TypeScript [`nextmail.connectedMailboxes.update()`](https://openemail.uk/docs/sdk/reference/connected-mailboxes#update); Python [`connected_mailboxes.update()`](https://openemail.uk/docs/python/reference/connected-mailboxes#update); Ruby [`connected_mailboxes.update`](https://openemail.uk/docs/ruby/reference/connected-mailboxes#update); PHP [`connectedMailboxes->update`](https://openemail.uk/docs/php/reference/connected-mailboxes#update); Go [`ConnectedMailboxes.Update`](https://openemail.uk/docs/go/reference/connected-mailboxes#update); Java [`connectedMailboxes().update`](https://openemail.uk/docs/java/reference/connected-mailboxes#update); CLI [`openemail connected-mailboxes update`](https://openemail.uk/docs/cli/reference/connected-mailboxes#connected-mailboxes-update).

### `ConnectedMailboxes.SyncAsync`

Sync a connected mailbox now

```csharp
Task<JsonObject> SyncAsync(
    string id,
    string? apiKey = null,
    CancellationToken cancellationToken = default)
```

Asks for a sync straight away instead of at the next interval, and returns the mailbox at once. The sync follows within seconds, and `lastSyncedAt` moves when it has finished.

A mailbox is synced every 30 seconds while mail comes in, and less often after it has been quiet for a while, down to every five minutes. A paused mailbox, or one that needs signing in, is not synced.

Scopes: `threads:write`.

**Parameters**

- `id` (`string`, required): Connected mailbox id such as `cmb_5c1e9a7b3d2f48e6a0b4c7d1`, as `ListAsync` returns it.
- `apiKey` (`string?`): Overrides the client's API key for this call only.
- `cancellationToken` (`CancellationToken`): Cancels the request.

**Returns**

A `JsonObject`: the mailbox as it was when the sync was asked for.

**Example**

```csharp
var mailbox = await client.ConnectedMailboxes.SyncAsync("cmb_5c1e9a7b3d2f48e6a0b4c7d1");

Console.WriteLine($"A sync starts within seconds. The last one finished at {mailbox["lastSyncedAt"]}");
```

**Notes**

- A missing mailbox is a 404 `connected_mailbox_not_found`.
- Asking twice does no harm, so the SDK retries this call after a network failure.

Also available in: API [`POST /connected-mailboxes/{id}/sync`](https://openemail.uk/docs/api/reference/connected-mailboxes#post-connected-mailboxes-id-sync); TypeScript [`nextmail.connectedMailboxes.sync()`](https://openemail.uk/docs/sdk/reference/connected-mailboxes#sync); Python [`connected_mailboxes.sync()`](https://openemail.uk/docs/python/reference/connected-mailboxes#sync); Ruby [`connected_mailboxes.sync`](https://openemail.uk/docs/ruby/reference/connected-mailboxes#sync); PHP [`connectedMailboxes->sync`](https://openemail.uk/docs/php/reference/connected-mailboxes#sync); Go [`ConnectedMailboxes.Sync`](https://openemail.uk/docs/go/reference/connected-mailboxes#sync); Java [`connectedMailboxes().sync`](https://openemail.uk/docs/java/reference/connected-mailboxes#sync); CLI [`openemail connected-mailboxes sync`](https://openemail.uk/docs/cli/reference/connected-mailboxes#connected-mailboxes-sync).

### `ConnectedMailboxes.DisconnectAsync`

Disconnect a mailbox

```csharp
Task<JsonObject> DisconnectAsync(
    string id,
    string? apiKey = null,
    CancellationToken cancellationToken = default)
```

Stops syncing and sending through the mailbox, forgets its password and removes its address from the workspace. The mail already copied in stays in Nextmail, and nothing is changed at the provider. An import of its history that is still running is cancelled.

To stop it for a while and keep it, use `UpdateAsync` with `paused` set to true. To use it again later, start over with `ConnectAsync`.

Scopes: `domains:write`.

**Parameters**

- `id` (`string`, required): Connected mailbox id such as `cmb_5c1e9a7b3d2f48e6a0b4c7d1`, as `ListAsync` returns it.
- `apiKey` (`string?`): Overrides the client's API key for this call only.
- `cancellationToken` (`CancellationToken`): Cancels the request.

**Returns**

A `JsonObject` with `object` set to `connected_mailbox`, the `id`, the `addressId` and the `email` of the mailbox, and `deleted` set to true.

**Example**

```csharp
var removed = await client.ConnectedMailboxes.DisconnectAsync("cmb_5c1e9a7b3d2f48e6a0b4c7d1");

Console.WriteLine($"{removed["email"]} deleted: {removed["deleted"]}");
```

**Notes**

- A missing mailbox is a 404 `connected_mailbox_not_found`.
- The SDK retries this call after a network failure. When the first attempt went through and only its answer was lost, the retry answers 404 `connected_mailbox_not_found`, which then means the mailbox is disconnected.

Also available in: API [`DELETE /connected-mailboxes/{id}`](https://openemail.uk/docs/api/reference/connected-mailboxes#delete-connected-mailboxes-id); TypeScript [`nextmail.connectedMailboxes.disconnect()`](https://openemail.uk/docs/sdk/reference/connected-mailboxes#disconnect); Python [`connected_mailboxes.disconnect()`](https://openemail.uk/docs/python/reference/connected-mailboxes#disconnect); Ruby [`connected_mailboxes.disconnect`](https://openemail.uk/docs/ruby/reference/connected-mailboxes#disconnect); PHP [`connectedMailboxes->disconnect`](https://openemail.uk/docs/php/reference/connected-mailboxes#disconnect); Go [`ConnectedMailboxes.Disconnect`](https://openemail.uk/docs/go/reference/connected-mailboxes#disconnect); Java [`connectedMailboxes().disconnect`](https://openemail.uk/docs/java/reference/connected-mailboxes#disconnect); CLI [`openemail connected-mailboxes disconnect`](https://openemail.uk/docs/cli/reference/connected-mailboxes#connected-mailboxes-disconnect).
