Importing contacts

Import a CSV from Mailchimp, HubSpot or a spreadsheet, and how Zeebra cleans it.

Open Contacts → Import and upload a CSV file with a header row. Exports from Mailchimp, beehiiv, Substack, Kit, MailerLite and HubSpot are recognised as they are; any spreadsheet saved as CSV works too.

The import page links a short guide to exporting your list from each of them: beehiiv, Substack, Mailchimp, Kit, MailerLite and HubSpot.

1. Match the columns

Zeebra guesses which column is which (email, first and last name, company, job title, phone, city, status, tags). Check the guesses, skip columns you don't need, map a column to one of your own properties, or turn it into a new one. Values are checked against the property: a date that doesn't exist, text in a number, or a choice that isn't an option is left out. Only the email column is required.

A status column from your old tool is respected: people marked unsubscribed, bounced or complained come in that way and are never emailed.

2. Say how these people agreed

  • Opted in: they asked for your emails (a signup form, a ticket purchase with a ticked box…). You confirm this and note how they agreed; the note is kept on every contact.
  • Prospects: you have their address but no agreement. They are kept and organised, but never get campaigns.

Only import people as opted in when they really agreed. Sending to people who didn't is what gets email accounts suspended.

3. Add them to a list or tag them (optional)

Choose a list (or create one) and tags for everyone in the file.

What the import cleans

Each address is checked, in this order:

  1. Not an address: skipped.
  2. Twice in the file: imported once.
  3. A typo in the domain (gmial.com): kept, flagged, with a suggested fix you can accept in bulk.
  4. Role addresses (info@, sales@): skipped unless you keep them.
  5. Throwaway inboxes: skipped.
  6. Domains that can't receive email: skipped.
  7. On your do-not-email list (or Zeebra's global one): never added.

When it finishes, the import shows how many were created, updated, skipped and flagged, and why.

Contacts you already have

An existing contact is updated with the file's non-empty values. Its status only ever gets stricter: an import can't bring back someone who unsubscribed, and an opted-in contact stays opted in.

From code

The API's import_contacts operation takes the CSV text and the same options; get_import shows its progress. See API and MCP.