Skip to content

CSV format and what gets skipped

Reference for the file you are about to import. For the steps themselves, see import contacts from a file.

Property Value
File types .csv, .tsv, .txt
Separators Comma, semicolon, tab
Encoding UTF-8
Maximum size 10 MiB per file
Maximum rows 50,000, counting the header row
Preview shown The first 10 rows

Size is usually what stops a file first. A wide export with many columns reaches 10 MiB at around 11,700 rows, well before the row cap. The row cap is there for the opposite kind of file: a very narrow list of bare addresses, tiny in bytes and enormous in rows.

A sheet of exactly 50,000 contacts plus a heading row is 50,001 rows and is refused. Split it into files of at most 50,000 rows each, counting the heading you give each one.

You can also paste rows straight out of a spreadsheet instead of uploading a file. A paste goes through exactly the same reading, the same checks, and the same wizard.

ColdMerge reads three separators and detects which one your file uses.

  • Comma is the CSV format’s own.
  • Semicolon is what spreadsheets export in countries that use a comma as the decimal point.
  • Tab is what copying cells out of a spreadsheet puts on your clipboard.

Nothing else is read. A pipe or a caret would be a fourth thing for detection to get wrong, and real exports do not use them.

Detection reads the first 20 rows, or roughly the first 64,000 characters, whichever comes first, and picks whichever separator yields the most email addresses. If two tie, it looks at which gives the tidier column shape, and a remaining tie answers comma.

If detection gets it wrong, choose the right separator from the Separator dropdown before selecting Read the rows. Rows are read once, so the correction belongs at that moment.

The file is read with a real CSV parser, not by splitting on the separator, so these all work:

  • A quoted field containing the separator.
  • A quoted field containing a line break. It counts as one row, the same row your spreadsheet shows.
  • A doubled quote inside a quoted field.
  • Windows line endings.
  • A byte order mark at the front of the file, which Windows exports add. It is stripped rather than welded onto your first column name.

Blank rows are dropped. Row numbers in the skip report still count them, so a number in the report points at the row you would open in your spreadsheet.

A row with more or fewer columns than the heading is kept rather than thrown away, because real exports have ragged rows and dropping one would lose a person you can see in your own file.

An unterminated quote is the one thing that fails the whole file. It is refused with a message rather than half-read.

Save your file as CSV UTF-8. Three encoding problems are refused by name so you know what to fix:

  • A file saved as UTF-16 is refused, and the message names the encoding. Re-export it as UTF-8.
  • A file saved in a legacy Western encoding such as Windows-1252 or Latin-1 is refused. Excel on a Windows machine writes this when you choose plain “CSV”, so choose “CSV UTF-8” instead. Left alone, accented names arrive as mangled characters and end up in a sent message.
  • A file that is not plain text at all is refused. The message names the exact character that gave it away and asks you to “check you are uploading a CSV export rather than a spreadsheet, a PDF, or a compressed file”. This is the message an .xlsx or a .zip gets: ColdMerge reads the bytes, not the file name, so renaming a spreadsheet to .csv does not get it in.

ColdMerge decides whether your first row names the columns using one rule: a heading row does not contain an email address.

The rule is narrow on purpose. Richer guesses (“headings are short”, “headings have no digits”) get real exports wrong, and the two mistakes do not cost the same. A heading read as a person creates one junk contact. A person read as a heading turns their address into a field name on every contact in the file.

That is why the answer is shown rather than applied quietly. Check the First row contains column names box at the mapping step, and untick it if your file has no headings.

The address column is detected from the values in each column, not from the column heading, because exports call it Contact, Email 1, or nothing at all. You can pick a different column at the mapping step.

A file where no column reads as addresses is refused at upload.

Before anything is stored or compared, an address is:

  1. Trimmed of surrounding padding.
  2. Lowercased.

So [email protected] and [email protected] are one person. Contacts are unique per workspace by their normalized address.

An address is refused as “not an address” when it:

  • Is longer than 254 characters, which is the longest an email path can carry.
  • Contains whitespace or invisible characters.
  • Has no @, or more than one.
  • Has a domain with no dot in it.
  • Contains any of , ; " ( ) < > on either side of the @.

That last rule matters more than it looks. Those characters are how addresses get glued together by a mis-read file: read with the wrong separator, an address cell comes back with the next column stuck on the end, and [email protected],Beta would otherwise become somebody’s identity.

An address wrapped in a display name, such as Ada <[email protected]>, is refused rather than unwrapped, because the wrapped form and the plain form are different strings and suppressing one would leave the other emailable.

Situation Result
The address is new A contact is created, and added to the destination list
The address already exists The existing contact is updated, and added to the destination list
The address is on your suppression list Skipped entirely. Nothing is created, updated, or added to a list
The email cell is not a usable address Skipped
The same address appeared earlier in this same file Skipped as a duplicate. The first occurrence is the one that counts

Re-importing a file with addresses you already have is safe.

  • Fields are merged one key at a time.
  • A blank cell is ignored. It never wipes a value you already had.
  • A column that is not in the file at all is left untouched.
  • Message history and suppression status are never affected.

There is deliberately no “blank cells clear the value” option anywhere in the import flow. Emptying a field is done on the contact’s own page.

An imported column heading becomes a field name you can use in a message as {{fieldName}}. Three kinds of column do not become a field:

  • A heading containing |, {, }, or a line break. Merge tokens cannot address those names. Rename the column at the mapping step to bring it in.
  • A heading named email. That name is reserved, because {{email}} is the one built-in token.
  • A column you leave unmapped. It is excluded rather than stored under an empty name.

Two columns cannot point at the same field name. One of them has to change.

A heading that matches a field name your workspace already uses lands on that existing field, so Company and company stay one field rather than becoming two. Headings that clearly mean first name or last name are proposed as the standard firstName and lastName fields.

Every skipped row is kept so you can download it, fix it, and upload just those rows again. Skipped rows are held for 30 days from the upload, after which the download is no longer available and the screen says so.

The count on the download button is a live count of what can still be downloaded, so it can differ from the number the summary reported when the import finished.