WarmblyDocs

Import mailboxes

Connect hundreds or thousands of mailboxes from a spreadsheet, a vendor export, or a pasted list.

Import mailboxes connects many mailboxes in one go. Open Accounts, choose Add account, then Import mailboxes. It takes the file your inbox vendor or your previous sending tool gave you, works out what each column means and where each domain's mail is hosted, and connects the rows in the background.

Only an address and a password are required. Servers, ports and encryption are found for you.

Three other sources skip the file entirely, each reached from the same Add account dialog:

All three create the same kind of import as a file: it runs in the background, shows the same progress, and groups failures by cause.

What it reads

  • A file: CSV, TSV or XLSX (the active sheet), up to 10 MB. A CSV may separate its columns with commas or semicolons (the separator spreadsheet apps use where the comma is the decimal mark); the header line decides which.
  • A pasted list: cells copied from a spreadsheet, CSV text, or one mailbox per line as address:password, address;password or address password. The address never contains a colon or a semicolon, so a password that does is read whole.
[email protected]:abcdabcdabcdabcd
[email protected]:abcd efgh ijkl mnop

One import takes up to 5,000 mailboxes. Split a larger file and import the rest separately.

The first row is treated as a header unless it holds an email address. First row is a header in the dialog overrides the guess.

Columns

Every column is matched to a field automatically. The first of these that applies wins:

  1. A mapping you confirmed before. When you import a file, the column mapping is saved for the workspace against that exact set of headers, so the next file with the same headers maps itself.
  2. The header name. Warmbly's own template and the column names in exports from Smartlead, Instantly, Saleshandy, Zapmail and InboxKit are recognised, along with the common spellings (smtp_server, app_password, login, From Email, and so on). A recognised export is named in the dialog.
  3. The values. A column of addresses, of 16-letter Google app passwords, of smtp. or imap. hostnames, or of port numbers such as 587 and 993 places itself even with no header.
  4. Jev, when the instance has TypeSafe configured, for columns nothing above placed. Jev sees the header text and a description of the values (for example "16 lowercase letters" or "hostnames"), never a value.

Every column can be reassigned by hand, or set to be ignored. Password columns are masked in the dialog and never shown again.

FieldHolds
emailThe mailbox address. The only column that has to be mapped
name, first_name, last_nameThe sender name. Without one, it comes from the address (alex.rivera@ becomes Alex Rivera)
passwordThe mailbox password
app_passwordAn app password. Preferred over password on providers that need one
smtp_password, imap_passwordA password for one server only
username, smtp_username, imap_usernameThe sign-in name, when it is not the address
smtp_host, smtp_port, smtp_securityThe outgoing server. Overrides detection
imap_host, imap_port, imap_securityThe incoming server. Overrides detection
daily_limitCampaign emails per day
min_waitSeconds between sends
warmupWarmup on or off (yes/no, true/false, on/off)
warmup_start, warmup_max, warmup_increase, warmup_reply_rateWarmup's first-day volume, daily ceiling, daily increase, and reply percentage
reply_toA reply-to address
signatureThe signature, as plain text
tagsTag names, separated by commas, semicolons or vertical bars, up to 20 per row
timezoneThe mailbox's time zone

Security columns accept SSL, TLS, SSL/TLS and STARTTLS, and the true/false SSL columns some exports use. Without one, security follows the port.

Where the servers come from

Servers are found once per domain, from DNS and the provider's own published settings, in this order:

  1. Known consumer domains (gmail.com, outlook.com, yahoo.com, icloud.com and the like).
  2. The domain's MX records, which identify Google Workspace, Microsoft 365, Zoho (with its data centre region), GoDaddy, Namecheap Private Email, IONOS, Hostinger, Fastmail, Yahoo, iCloud, Migadu, Purelymail, Rackspace, OVHcloud, Yandex and GMX.
  3. The domain's own Mozilla autoconfig file.
  4. The Thunderbird ISPDB, on Warmbly Cloud and on a self-host that sets MAILHOST_ISPDB=true.
  5. RFC 6186 SRV records.

The preview lists each domain with its provider, the servers found, and whether SPF, DKIM and DMARC are published. smtp_host and imap_host columns, and the port and security columns, override what detection found. A domain nothing finds needs those columns, or the servers entered on each row after the import.

Each mailbox is labelled with where it is hosted and how it signs in. The API returns these as mail_host and auth_method; a mailbox whose host is not recorded yet, such as one connected before the labels existed, is classified in the background from its domain.

What each provider needs

HostThe password must beWhere to get it
Google Workspace, GmailA 16-letter app password. Spaces are removed for you. None on a Workspace domain an admin grant coversmyaccount.google.com/apppasswords, after turning on 2-Step Verification. See Gmail and Google Workspace
Microsoft 365, Outlook.comNo password: each mailbox connects with Microsoft sign-in, or through an admin grant when one covers the domainThe Sign in button on the row
Yahoo MailAn app passwordlogin.yahoo.com/account/security
AOL MailAn app passwordlogin.aol.com/account/security
iCloud MailAn app-specific passwordaccount.apple.com, under Sign-In and Security
FastmailAn app password with IMAP and SMTP accessSettings, Privacy and Security, Manage app passwords
Yandex MailAn app passwordid.yandex.com/security/app-passwords
Zoho MailThe account password, or an app password when two-factor authentication is onZoho Accounts for your region, under Security, App Passwords
GoDaddy, Namecheap Private Email, IONOS, Hostinger, OVHcloud, Migadu, Purelymail, Rackspace Email, GMXThe mailbox passwordYour provider's control panel
Proton MailCannot connect this waySee Proton Mail below
Anything elseThe mailbox passwordYour provider. Servers come from autoconfig, the ISPDB, SRV records, or your columns

Google

A Google row whose password is not a 16-letter app password is flagged in the preview before anything is tried: Google refuses the account password over IMAP and SMTP. On an instance that connects new Gmail mailboxes with Google sign-in (gmail_oauth_connect in GET /auth/config), such a row waits for sign-in instead, like a Microsoft row.

Microsoft

Exchange Online no longer accepts passwords over IMAP, so Microsoft 365 and Outlook.com rows connect with Microsoft sign-in. The import parks them as needs sign-in and the rest of the file carries on. Each has a Sign in button that opens Microsoft's sign-in with the address already filled in. When that address connects, from the row or by any other route, the row closes and the import's settings are applied to the mailbox.

A Microsoft 365 admin can grant consent once for the whole organization, after which each sign-in is one click. To skip the sign-ins altogether, connect the whole organization instead: rows on its domains then connect with no sign-in at all. Microsoft has also announced that SMTP AUTH with basic authentication becomes disabled by default for existing tenants at the end of December 2026, which is another reason these mailboxes use sign-in rather than a password.

Proton Mail

Proton Mail offers no IMAP or SMTP sign-in to other apps; only its Bridge does. Proton rows are flagged as unable to connect. On a self-hosted instance whose worker runs on the machine the Bridge is on, map smtp_host and imap_host columns (and ports) to the Bridge and use the Bridge's own password. See local mail relays.

Import from an inbox vendor

Choose Add account, then Inbox vendor, pick the vendor and enter what it asks for. Warmbly checks the key with the vendor before saving it, lists the mailboxes in that vendor account (marking the ones already in the workspace), and imports the ones you pick, or every one not yet connected.

VendorAsks forWhere to find the key
InboxKitAPI key and workspace ID (a UUID)Settings > API & Integrations in the InboxKit dashboard
ZapmailAPI key; optionally a workspace ID (blank is your primary workspace) and a mailbox type (GOOGLE or MICROSOFT, blank imports both)Settings > Integrations > API in the Zapmail dashboard
MailforgeAPI keySettings > API keys in the Mailforge dashboard
InfraforgeAPI key; optionally a workspace ID (blank imports every workspace)Settings > API keys in the Infraforge dashboard
MaildosoAPI key (a personal access token)Settings > API Keys in the Maildoso dashboard
Cheap InboxesAPI key, starting with ci_live_Integrations > API in the Cheap Inboxes dashboard
ScaledMailAPI key and organization IDSettings in the ScaledMail dashboard

One vendor account lists up to 10,000 mailboxes.

  • Credentials are read when each row is worked. Picking mailboxes stores only which ones you picked. The password, app password and servers of each are fetched from the vendor at the moment its row connects, and the row is then judged exactly like a file row: Google mailboxes need the app password the vendor holds (or an admin grant over the domain), and Microsoft mailboxes wait for sign-in unless a grant covers them.
  • The key is sealed and never shown again. The API key and IDs are sealed with the workspace's own encryption key. The list of connections shows each one's vendor, label, status and mailbox count, never the key. Update replaces the key after checking the new one with the vendor.
  • Passwords the vendor rotates are picked up. An SMTP and IMAP mailbox that came from a vendor and has stopped with an unresolved connection error is looked at every 15 minutes. When the vendor now holds a different password for it, Warmbly verifies that password against the server and reconnects the mailbox with it. Each mailbox is tried at most once every 6 hours, so a password that still fails is not retried on every pass.
  • A refused key marks the connection. When the vendor stops accepting the key, the connection shows as invalid with the vendor's reason, and rows that needed it fail as vendor_unauthorized until the key is updated.
  • Deleting the connection keeps the mailboxes. They stay connected and keep sending; they are no longer reconnected automatically when the vendor rotates a password.

Connect a whole Google Workspace domain

A Google Workspace super admin can authorize Warmbly for the whole domain with domain-wide delegation. Every mailbox on the domain then connects through that one grant: no app passwords, nothing that expires when someone changes a password, and nothing for each mailbox owner to do. It is the recommended way to connect Workspace mailboxes.

Choose Add account, then Google, then Whole Workspace domain. The dialog shows a client ID and the scopes to authorize. On a self-hosted instance the option stays switched off until the operator has set up a Google service account; see whole-domain mailbox connects.

First, the super admin authorizes the client ID. This has to happen before the domain is proved, because Warmbly checks the authorization straight away:

  1. Sign in to admin.google.com as a super admin and go to Security > Access and data control > API controls, then Manage domain-wide delegation.

  2. Choose Add new and paste the client ID the dialog shows. It is a long number; it never ends in apps.googleusercontent.com.

  3. Enter exactly these three scopes, comma separated:

    https://www.googleapis.com/auth/gmail.modify,https://www.googleapis.com/auth/gmail.settings.basic,https://www.googleapis.com/auth/admin.directory.user.readonly
  4. Choose Authorize, and allow a few minutes for Google to apply it.

Then, back in Warmbly, enter the domain and a super admin address on it, and prove the domain as below.

Prove the workspace controls the domain

The client ID belongs to the instance, not to your workspace, so authorizing it says nothing about which workspace asked. A grant is recorded only for the workspace that proves it controls the domain, in one of two ways:

  • Sign in as the administrator. When the instance has a Google sign-in app, Warmbly opens Google's sign-in for the admin address you entered. The sign-in has to be that exact address, verified by Google, on that Workspace domain.

  • Publish a DNS record. Always available, and the only way on an instance without a Google sign-in app. Add this TXT record at your DNS provider, then confirm:

    TypeNameValue
    TXT_warmbly.<domain>warmbly-verify=<value>

    The value is unique to your workspace and that domain, so a record published for another workspace proves nothing for yours. It is the same record that proves the domain for a root redirect, so one record serves both. DNS changes can take a while to appear; confirm again once the record resolves.

A sign-in link is valid for 15 minutes, works once, and only for the member who started it, in the same workspace. Recording the grant also needs a recent confirmation of your own sign-in.

After the proof, Warmbly checks the grant itself: it reads the admin's own Gmail profile and the domain's user directory, and the directory must list the address as a super administrator. A change in the Admin console can take a few minutes to apply, so a refusal straight after saving it is worth one more try. The grant covers the domain and every other domain that appears on its users' addresses. Making the grant again for the same domain re-verifies and updates it rather than adding a second one.

The admin address is used only to read the directory, so you can pick which mailboxes to connect. It is not connected itself, and no token for it is stored. The first two scopes are the same ones a mailbox connected with Google sign-in holds; the third reads the list of users.

Pick users from the directory, or connect every active one not yet in the workspace. A user whose mailbox is already here on its own Google sign-in is marked as one to move: connecting it puts that mailbox onto the grant in place, keeping its history, campaigns and warmup, and connecting everyone includes it. Each mailbox is checked against Gmail as it connects and runs on Gmail's API, like a mailbox connected with Google sign-in. No token is stored for any of them: the backend mints a short-lived one each time a worker needs it.

The grant is checked again every hour. When Google stops honoring it (the entry was removed in the Admin console, or a scope was dropped), the grant shows as invalid and its mailboxes stop. A check that gets no answer from Google changes nothing. When a later check succeeds, the mailboxes that stopped because of it are put back to work on their own; one you switched off stays off. Check again runs the check straight away. Deleting the grant stops every mailbox it connected.

Connecting mailboxes through a grant and deleting a grant both reach a whole domain's mail, so like recording one they need a recent confirmation of your sign-in.

Connect a whole Microsoft 365 organization

A Global Administrator can approve Warmbly once for the whole Microsoft 365 organization. Mailboxes then connect through Microsoft Graph with application permissions: no sign-in per mailbox. It is the recommended way to connect Microsoft 365 mailboxes.

Choose Add account, then Microsoft, then Whole organization, and have a Global Administrator (or Privileged Role Administrator) sign in on the Microsoft consent screen that opens and choose Accept. Warmbly records the organization only when the person who signed in holds one of those roles. That is the only step on the Microsoft side, and it happens once. On a self-hosted instance the option needs the operator's Microsoft app set up first; see whole-domain mailbox connects. The consent gives the instance's Microsoft app these application permissions in the organization:

PermissionWhat it is for
Mail.ReadWriteRead replies and move messages
Mail.SendSend mail
User.Read.AllList the organization's users, so you can pick which mailboxes to connect

The organization that is recorded is the one the administrator signed in to, as Microsoft reports it when the consent completes, so a grant can only ever name the organization that consented. Warmbly then obtains a token for it and reads its users; the domains on their addresses (guests excluded) become the domains the grant covers. The consent link is valid for 15 minutes, works once, and only for the member who started it, in the same workspace. Recording the grant needs a recent confirmation of your own sign-in, as do connecting mailboxes through it and deleting it. Consenting again for the same organization updates the grant rather than adding a second one.

Application permissions reach every mailbox in the organization. Microsoft lets an Exchange administrator narrow that to the mailboxes you choose, and we recommend it. With an application access policy, in Exchange Online PowerShell:

Connect-ExchangeOnline
# A mail-enabled security group holding the mailboxes Warmbly may use
New-DistributionGroup -Name "Warmbly senders" -Type Security -PrimarySmtpAddress warmbly-[email protected]
Add-DistributionGroupMember -Identity "Warmbly senders" -Member [email protected]
# <app id> is the Application (client) ID of the app you consented to, under Enterprise applications in the Microsoft Entra admin center
New-ApplicationAccessPolicy -AppId <app id> -PolicyScopeGroupId warmbly-[email protected] -AccessRight RestrictAccess -Description "Warmbly sends only from these mailboxes"
Test-ApplicationAccessPolicy -Identity [email protected] -AppId <app id>

Microsoft's newer RBAC for Applications does the same with a management scope and role assignments (New-ManagementScope, then New-ManagementRoleAssignment -App <app id> -Role "Application Mail.ReadWrite" and "Application Mail.Send" with -CustomResourceScope). Its scoped assignments add to what the consent grants, so remove the organization-wide Mail.ReadWrite and Mail.Send consent in Microsoft Entra when you move to it. A mailbox outside the policy is refused when it connects.

Pick users from the directory, or connect every enabled one not yet in the workspace. Only users with a mail address are listed. A mailbox already here on its own Microsoft sign-in is marked as one to move, as with Google: connecting it puts it onto the grant in place, and connecting everyone includes it. Moving is optional for Microsoft mailboxes; their own sign-in keeps working. Each mailbox is checked against Microsoft Graph as it connects; a disabled account, or a user without an Exchange Online license, has no mailbox to connect and is refused. As with Google, no token is stored: the backend mints one each time a worker needs it. The grant is checked every hour, its mailboxes stop when the consent is withdrawn and restart when a check succeeds again, a check that gets no answer from Microsoft changes nothing, and deleting it stops every mailbox it connected.

When a file meets an admin grant

A file or pasted list does not need to know about grants. When an active grant covers a row's domain, the row connects through it:

  • a Google Workspace row connects through the domain's Google grant, and any password on the row is ignored
  • a Microsoft 365 row connects through the organization's grant instead of waiting for a sign-in

The same holds for rows from an inbox vendor. The preview marks these rows, and each connected mailbox is labelled with the sign-in method delegated. A grant that stops working fails its rows as mailbox_grant_inactive; check the grant, then retry them.

Mailboxes already connected

An address already in the workspace, connected by anyone, is matched case-insensitively. If a mailbox is already connected decides what happens:

  • Update (the default): the new password replaces the stored one after it is verified against the server, and the mapped settings are applied. The sender name changes only when the file names one.
  • Skip: the mailbox is left as it is and the row is marked skipped.

A mailbox connected with Google or Microsoft sign-in only takes the settings; there is no password to replace. When an active grant covers its domain, the row moves it onto the grant instead, in place, keeping its history, campaigns and warmup (see moving off per-mailbox Google sign-in); Skip leaves it as it is. When the same address appears twice in one file, only the first row is imported and the later ones are skipped as Listed twice in the file.

Settings for every mailbox

The dialog sets these for every mailbox the import connects or updates. A mapped column wins over them for its own row.

  • tags
  • daily limit
  • time between sends (in minutes in the dialog; the min_wait column is in seconds)
  • warmup on or off, with its start, maximum, daily increase and reply rate
  • reply-to, signature and time zone

Tags are added to the ones a mailbox already has. A tag named in the tags column that does not exist yet is created. A setting that cannot be applied never fails its row: the mailbox is connected and the row's message says what did not apply. A value that cannot be read at all, such as text in a limit column, fails that row before it is tried. See sending behavior and warmup for sensible values.

Tracking domains and root redirects

The review step lists each domain in the import, and two choices can be made per domain there. Both are applied as the import connects the domain's mailboxes, and both can be changed later on sending domains.

  • Tracking domain. The subdomain that carries the opens and clicks of every mailbox on the domain. Warmbly offers one already in use by a verified mailbox on the domain, or one whose DNS already points at this instance (it tries track, t, link, links, click, go, email and trk), or suggests track.<domain>. When a connected inbox vendor account holds the domain and its API can write DNS records, Warmbly writes the CNAME through the vendor for you. Otherwise you add it; the host is set either way, and links switch to it once the record resolves. See custom tracking domain.
  • Root redirect. A website address that visitors to the bare domain are sent to, such as https://yourcompany.com. It is set up once the import has connected a mailbox on the domain. When a connected inbox vendor account holds the domain and can forward it, the vendor's own forwarding is used and there is no DNS to add. Otherwise Warmbly serves the redirect itself once DNS proves you control the domain. See root redirects and domains held by an inbox vendor.

A setting that cannot be applied does not fail the row: the mailbox connects and the row's message says what did not apply. In the API these are the tracking_domains and redirects objects in options, each keyed by domain, up to 500 domains each.

While it runs

The import runs on the server. Closing the tab does not stop it, and everyone in the workspace who can manage mailboxes sees its progress live, with the mailbox list filling in behind it. Recent imports in the dialog reopens one later.

Rows connect 8 at a time, and at most 3 at once against any one mail host, since providers throttle bursts of sign-ins from one address. Each credential is verified against the live server before it is saved, exactly like a single connect, so wrong credentials fail here rather than at the first send.

Rows past the workspace's mailbox allowance fail as Mailbox limit reached; the preview says how many will fit. Raise the allowance and retry them.

Cancelling stops the rows not yet started. Rows already connecting finish.

When rows fail

Failures are grouped by cause, each with the fix. The same keys appear as cause on each row in the API.

CauseTitle
missing_emailNo email address
invalid_emailNot an email address
duplicate_rowListed twice in the file
missing_passwordNo password
unknown_serversMail servers not found
invalid_valueA value could not be read
microsoft_signinConnect with Microsoft sign-in
google_signinConnect with Google sign-in
provider_unsupportedProvider cannot connect over IMAP
allowance_reachedMailbox limit reached
no_workerNo worker available
creator_removedImport owner left the workspace
vendor_unauthorizedVendor refused the API key
vendor_unreachableVendor did not return the credentials
mailbox_grant_not_configuredAdmin connections are not set up here
google_delegation_unauthorizedGoogle refused the domain-wide delegation
microsoft_consent_missingMicrosoft 365 admin consent is missing
mailbox_grant_mailbox_unreachableNo mailbox for this account
mailbox_grant_domain_mismatchDomain not covered by the grant
mailbox_grant_inactiveThe admin grant stopped working
internalSomething went wrong
google_app_password_requiredGoogle needs an app password
google_bad_credentialsGoogle did not accept the app password
google_imap_disabledIMAP is turned off in Google
google_web_login_requiredGoogle wants a browser sign-in first
microsoft_smtp_auth_disabledSMTP sign-in is turned off in Microsoft 365
microsoft_security_defaultsMicrosoft security defaults block passwords
microsoft_conditional_accessA Microsoft sign-in policy blocked this
microsoft_basic_auth_disabledMicrosoft needs Microsoft sign-in
microsoft_bad_credentialsMicrosoft did not accept the password
yahoo_app_password_requiredYahoo needs an app password
aol_app_password_requiredAOL needs an app password
icloud_app_password_requirediCloud needs an app-specific password
zoho_app_password_requiredZoho refused the password
fastmail_app_password_requiredFastmail needs an app password
yandex_app_password_requiredYandex needs an app password
imap_disabledIMAP is turned off for this mailbox
account_lockedThe account is locked or disabled
too_many_loginsToo many sign-in attempts
auth_unavailableThe server does not take a password here
auth_refusedThe server refused the sign-in
host_not_foundThe server name does not exist
host_unreachableThe server could not be reached
port_blockedThe mail port looks blocked
tls_failedThe secure connection failed
cleartext_refusedEncryption is required
timeoutThe server did not answer in time
temporaryThe server asked to retry later
server_declinedThe server did not accept the connection

Then fix them without re-uploading:

  • Fix one row: enter a new password or app password, a sign-in username, or the servers, and the row is queued again.
  • Retry a group: requeue every failed row with one cause, optionally with one new password for all of them.
  • Download failed rows: a CSV of every row that did not connect, with its line number, the columns you uploaded minus passwords, and status, problem and how_to_fix. Add the passwords back before uploading the fixed file.

A retry is possible for 7 days after the import finishes. After that the row's credentials are gone and it has to be imported again.

What is kept

  • Credentials of rows that did not connect are kept, sealed with the workspace's own encryption key, for 7 days after the import finishes so a retry works, then deleted.

  • A finished import and its rows (address, status, cause, and the non-password cells shown in the download) are deleted after 30 days.

  • A connected mailbox's credentials are stored exactly like any other mailbox's.

  • An inbox vendor connection (its sealed key and IDs) is kept until you delete it. So is an admin grant, which holds the domains it covers, the tenant, and for Google the admin address; it holds no token.

The saved column mappings and vendor connections travel with a workspace export. Imports themselves do not, and neither do admin grants: a grant is recorded only after the workspace proves the domain or organization on the instance it runs on, and an archive proves nothing. The mailboxes a grant connected do travel. On the destination, make the grant again, then pick those users in its directory (they are listed as already connected, so connecting every user not yet here skips them), or import a file of their addresses with Update for existing mailboxes. Each one relinks the mailbox that arrived, with its history and settings, rather than adding a second one.

API

The import is available to a signed-in session under /emails/imports, never to an API key, because it carries passwords. Vendor connections (/emails/vendors), admin grants (/emails/grants) and sending domains (/emails/domains) are session-only for the same reason. See endpoints for the routes. POST /emails/onboarding/smtp-imap/bulk remains for connecting up to 50 SMTP and IMAP mailboxes in one synchronous call.

On this page