Bulk import via CSV
Bulk import connects multiple SMTP inboxes in one pass from a CSV file, instead of using the SMTP / Manual form one inbox at a time. Each row can also auto-start warmup on the inbox it connects, with its own warmup mode, volume, reply rate, and sending schedule.
On this page
CSV column format
The CSV needs a header row. Columns are matched by header name, not position — so the columns can appear in any order — but header matching is case-sensitive, so Email will not satisfy the email requirement.
| Column | Required | Notes |
|---|---|---|
email | Always | Must pass email-format validation |
smtpHost | Always | Up to 255 characters |
smtpPort | Always | Whole number, 1–65535 |
smtpSecureMode | Always | Exactly STARTTLS, SSL_TLS, or NONE (case-insensitive) |
smtpUsername | Always | Up to 255 characters |
smtpPassword | Always | Up to 500 characters — never trimmed |
autoStartWarmup | Always | Exactly Y or N (case-insensitive) |
displayName | Optional | Up to 120 characters |
imapHost | Only if autoStartWarmup = Y | |
imapPort | Only if autoStartWarmup = Y | |
imapSecureMode | Only if autoStartWarmup = Y | Exactly STARTTLS, SSL_TLS, or NONE |
imapUsername | Only if autoStartWarmup = Y | |
imapPassword | Only if autoStartWarmup = Y | |
warmupMode | Optional | Blank, RAMPING, MAINTENANCE, or CUSTOM — blank defaults to RAMPING |
customVolume | Only if warmupMode = CUSTOM | Whole number |
replyRate | Optional | Whole number if given — blank uses warmup's own default |
sendingSchedule | Optional | Must match an existing workspace schedule name |
If autoStartWarmup is N, the imapHost/imapPort/imapSecureMode/imapUsername/imapPassword columns can still be filled in, but they're stored without being validated — and warmupMode, customVolume, replyRate, and sendingSchedule are ignored entirely, not even format-checked.
Rows where every column is blank are dropped automatically before anything else runs. A CSV with no usable rows left after that is rejected with "No usable rows were found in this CSV." A sample CSV matching this exact column set is available from the import dialog.
Validation order
Each row is validated and processed through the same sequence, in this order:
- Format checks — the column rules above, checked locally with no network calls. A row that fails here never reaches the network.
- Sending schedule lookup — if a
sendingSchedulename was given, it's resolved against the workspace before anything else. An unmatched name fails the row here: "Sending schedule "{name}" was not found in this workspace." - Live SMTP and IMAP pre-checks — only run when
autoStartWarmup = Y. SMTP is checked first with a real connection and authentication attempt; IMAP is only checked if SMTP passes. A row withautoStartWarmup = Nskips both pre-checks — the inbox connection step below does its own SMTP verification regardless. - Connect the inbox — always attempted (this is the same connect call the manual SMTP / Manual form uses), including its own internal SMTP re-verification even on a warmup row that already passed the pre-check.
- Start warmup — only if
autoStartWarmup = Yand the inbox connected. Applies the same defaults as starting warmup manually: RAMPING mode, roughly 15% reply rate, and the workspace's default sending schedule. - Apply overrides — any row-requested
warmupMode/customVolume,replyRate, orsendingScheduleare applied on top of step 5's defaults. Each of the three overrides is applied independently, so one failing doesn't block the other two.
Pre-import warnings
Two warnings can appear on individual rows before you confirm the import. Both are informational only — neither one blocks the row from being imported.
Port / secure-mode mismatch. Shown when a row's port is exactly one of the conventional values below but its secure mode doesn't match:
| Port | Expected secure mode |
|---|---|
| 587 (SMTP) | STARTTLS |
| 465 (SMTP) | SSL_TLS |
| 143 (IMAP) | STARTTLS |
| 993 (IMAP) | SSL_TLS |
The message reads: "Port {port} is usually paired with {SSL/TLS or STARTTLS}, not {whatever the row's secure mode is}." The IMAP half of this check only runs on rows with autoStartWarmup = Y.
customVolume ignored. Shown when a row sets customVolume but warmupMode isn't CUSTOM — since customVolume only ever takes effect in CUSTOM mode; RAMPING and MAINTENANCE both use their own fixed volume. The message reads: "customVolume ({value}) will be ignored — warmupMode is {blank (defaults to RAMPING) or whatever was given}, not CUSTOM. {RAMPING or MAINTENANCE}'s own fixed volume will be used instead."
Row cap
20 rows per upload. A CSV with more rows than that is rejected before any row is sent, with: "This file has {n} rows — imports are capped at 20 rows per upload. Split this file and import it in batches." At least 1 row is required.
Rows are processed strictly one at a time (see Known limitations), so a batch where every row needs both SMTP and IMAP pre-checks can take several minutes worst case. The 20-row cap exists specifically to keep a full batch inside that window.
Per-row results
Each row gets three independent results, not one pass/fail — because connecting the inbox, starting warmup, and configuring warmup overrides can each succeed or fail on their own. Every result is one of Done, Failed, or Not requested.
- Connected — never
Not requested, since connecting is always attempted.Failedcovers everything upstream of a successful connect: a format-validation failure, a sending-schedule lookup miss, a failed SMTP/IMAP pre-check, or the connect call itself failing. - Warmup started —
Not requestedif the row'sautoStartWarmupwasN. OtherwiseFailedif starting warmup errors (for example, no active warmup subscription, or the workspace's shared monthly warmup volume was already used up by an earlier row in the same batch) — note that Connected staysDonein that case, since the inbox itself connected fine.Doneonce warmup starts. - Warmup configured —
Not requestedwhenever warmup wasn't started or failed to start, since overrides are only applied after a successful start.Failedif any of the up-to-three overrides (warmupMode/customVolume,replyRate,sendingSchedule) errors, with the specific failing override(s) named in the message. A row that requested no overrides at all (blankwarmupMode, blankreplyRate, blanksendingSchedule) still getsDonehere, since there was nothing to fail — it's running on step 5's RAMPING defaults.
Known limitations
- Rows are processed strictly one at a time, synchronously, inside a single request — there's no background queue. This is deliberate, partly to stay well under the warmup provider's own request-rate limit, not just to avoid hammering target mail servers.
- No duplicate-email detection. Nothing in the import checks for the same
emailappearing twice in one CSV, or against an inbox that's already connected in the workspace — each row is processed independently. Results are matched back to rows by position (row 1, row 2, ...), not by email, specifically because an email can legitimately repeat across rows. - Passwords are never trimmed.
smtpPasswordandimapPasswordare used exactly as given, including any leading or trailing whitespace — every other column is trimmed.
Where to go next
Next: Warmup overview