eusend
Dashboard

Contacts CSV

Import and export contacts in bulk from any audience detail page, with automatic column mapping.

Audiences support bulk contact management via CSV import and export, from any audience detail page.

Importing

Choose Import CSV and pick a file. Nothing is sent until you have confirmed the mapping.

1. We read your header row

The file is parsed in your browser. The delimiter is detected rather than assumed — comma, semicolon, tab and pipe all work, so a spreadsheet exported by Excel in a European locale (which uses ;) imports without you having to convert it first. Quoted fields are handled properly, so a value like "Doe, Jane" stays one field.

2. We map the columns for you

Each column is matched to a eusend property, and you get a table showing the column name, a sample value from your file, and the property we chose. Every row is editable: change a mapping, or untick a column to leave it out.

Matching is case- and punctuation-insensitive, so Email, email_address and E-Mail Address all find email. Columns we don't recognise are left unmapped rather than guessed at.

PropertyRequiredDescription
emailyesContact email address. Rows without a valid address are skipped and counted.
first_namenoUsed in {{first_name}} template variables.
last_namenoUsed in {{last_name}}.
subscribednofalse, no, 0 or unsubscribed opts the contact out. Anything else is opted in.
created_atnoOriginal signup time. Applied to new contacts only.

Any other column can be brought in as a custom property: pick Custom property in that column's dropdown and it is stored under a name derived from the header, so Plan Name becomes plan_name and renders as {{plan_name}} in a broadcast. A header that would collide with a built-in variable is prefixed rather than refused — a column headed Email mapped as a property becomes custom_email.

A contact holds at most 20 properties; columns past that are left out rather than failing the import, and values longer than 500 characters are truncated. Empty cells are skipped, not written as blanks — see the rules below.

3. Import

Contacts are upserted in chunks of 1,000, so a list of any size imports in one go. Addresses are lowercased and de-duplicated — if the same address appears twice, the last row wins, and the summary tells you how many were merged.

What an import will never do

Re-importing a list is a normal thing to do, and it is safe. Two rules make it so:

  • An unmapped column changes nothing. Importing a file of just email,subscribed will not blank the names of the contacts it touches.
  • An empty cell changes nothing either. Properties merge rather than replace, so a blank plan cell leaves whatever plan the contact already had. To clear a property, edit the contact.
  • An import can add an opt-out, never remove one. If somebody has unsubscribed, a spreadsheet saying otherwise will not put them back on the list — not with subscribed,true, and not by omitting the column. Re-subscribing is a consent decision, so it lives on the contact itself (or PATCH /audiences/:id/contacts/:contactId), one person at a time.

Exporting

Exported files use the full column set and can be re-imported without losing anything — including who has unsubscribed and when each contact joined.

export column order
email,first_name,last_name,subscribed,created_at

Every custom property present in the exported contacts is appended as its own column, named exactly as the property is. Those names round-trip: re-importing the file matches each one straight back onto the property it came from.

Editing one contact

The bulk paths are for lists. To change a single contact — its name, whether it is subscribed, or its custom properties — use the pencil on its row in the contacts table. Unlike an import, that editor replaces the property set, so removing a row there removes the property from the contact.

Importing through the API

The dashboard is doing what you could do yourself:

await client.audiences.batchCreateContacts(audienceId, {
  contacts: [
    { email: 'alice@example.com', firstName: 'Alice', lastName: 'Smith' },
    { email: 'bob@example.com', unsubscribed: true, createdAt: '2024-02-01T10:00:00.000Z' },
  ],
})

Up to 1,000 contacts per call. See Audiences and contacts for the full endpoint.