Skip to main content

Importing contacts from Excel or CSV (with consent)

Bring in a customer list from a CSV or Excel file: match the columns (headers in any language of the app), choose the country for local numbers and what to do with people already in Contacts, declare the marketing consent they gave, check the file, import, and download errors.csv. Also: Add contact for one person.

Import contacts from Excel or CSV, with their consentWatch on YouTube

Contacts → Import (/app/contacts/import) brings in a whole customer list from a file. Add contact on the Contacts page adds one person by hand. Nothing is saved until you have checked the file and pressed the import button.

Before you start

  • Importing needs the Import contacts task (Owners and Admins by default; an Owner or Admin can give it to anyone with Edit access on Settings → Members, see Roles and tasks). Without it the Import button is hidden and the page says Importing contacts needs the Import contacts task. Ask an Owner or Admin.
  • Add contact needs the Manage contacts task (Owners, Admins and Editors by default).
  • The file: CSV (UTF-8, UTF-16 or Windows Arabic; commas, semicolons or tabs) or Excel .xlsx (the first sheet). Up to 20 MB, 100,000 rows and 200 columns. An old Excel .xls is refused: in Excel choose File > Save As > Excel Workbook (.xlsx) or CSV UTF-8.
  • The first row must name the columns, for example Name, Phone, Email or الاسم، الجوال، البريد الإلكتروني. Every person needs a phone number or an email.
  • To import custom details (membership tier, birthday...), create the fields first in Custom contact fields.

Step by step: import a file

  1. On Contacts press Import.
  2. File: press Choose a file, pick it, press Upload. You see Reading the file…, then the columns.
  3. Columns: under Match the columns each column of your file has an Import as box. We guess from the headers in the app's ten languages, with or without accents (الجوال, Téléphone, Handy or Cep telefonu → Phone (WhatsApp), الاسم, Nom complet or Nama → Name, a header that matches a custom field → that field). Beside a first-name column, a bare Nom or Name is taken as the last name; beside a surname column, Nome or Nombre as the first name. Set columns you do not need to Don't import. Example shows a value from the file. When a column set to Don't import looks like phone numbers or email addresses (and no other column is set to them), a yellow line under it says so, for example This column looks like phone numbers, but it is set to “Don't import”, so they will not be imported. Choose “Phone (WhatsApp)” to import them.
  4. Under Options:
  • Country for local numbers: numbers written without a country code (07400 123456, or 7400 123456 when Excel dropped the zero) are read as numbers of this country. Arabic digits (٠٥٠...) are fine. A Country column in the file wins for its row. It starts as your company's country (with none set it reads Choose a country, and only numbers written with their country code are read); the list has every country, named in your language, in alphabetical order under All countries (the country your browser says you are in, when it says, comes first under Suggested).
  • People already in Contacts (same phone or email): Update them with the file's values (filled cells replace what the contact had, empty cells never clear anything, tags are added, a phone or email is only added when the contact has none) or Skip them.
  • Extra tags for everyone imported (separated by commas): up to 10 tags, each up to 50 characters (a leading # is ignored). More shows Add at most 10 extra tags. Remove some, or add them later with Add tags. under the box, and a longer tag A tag can be at most 50 characters. Shorten it, or split it with a comma.; Continue waits until the box is right.
  1. Press Continue.
  2. Consent: choose No - they have not agreed, or I don't know or Yes - they agreed, and I can say how. For yes, tick the Channels they agreed to (WhatsApp, SMS, Email), choose Where did they agree?, write How did these people agree? (at least 10 characters, for example "They ticked Send me offers on WhatsApp when joining our loyalty programme"), fill When they agreed (optional) if you know it, and tick I confirm these people gave this consent and I can show proof if asked.
  3. Press Check the file. The check reads every row and saves nothing (Checking n of N rows…).
  4. Result of the check shows Ready to import, With problems, New contacts, Already in Contacts and Repeated in the file, and the First rows with problems with the reason. Change settings takes you back; Download errors.csv gives every problem row. A contact holds at most 20 tags: when some people would pass that, the check says, for example, 3 contacts would pass the limit of 20 tags. They keep their tags and get this import's own tag; the other new tags are added only while there is room. A file made with Export CSV imports as it is: the apostrophe in front of a number such as '+447400123456 is taken off.
  5. Press Import n contacts. Importing n of N… shows the progress. You can leave the page: the import carries on, and Contacts → Import → Recent imports reopens it (Open). An upload you left before importing (at Columns, Consent or after Check the file) shows in Recent imports as Not finished, with Continue (back to where you left off) and Discard. Discard asks "Discard the upload "(file)"? Nothing from it was imported. Its rows and the stored file are deleted." and removes it from the list. Uploads left unfinished for 7 days are discarded automatically; nothing in Contacts changes either way.
  6. When you see Import finished., press View imported contacts to see the list, or Download errors.csv (shown, with the line The rows that were not imported, with the reason, in the file's own columns., only when some rows were not imported). Under the totals, Everyone this import created or updated is on the list "Import – customers.csv – 2026-09-24" (n people). names the list the import made; Open the list opens it on Contacts → Audiences (see next section).

The import's list

When an import finishes, everyone it created or updated is put on a new list (a static audience) named Import – <file name> – <date>, for example Import – customers.csv – 2026-09-24. Use it like any list: pick it as the audience of a WhatsApp broadcast, open it on Contacts → Audiences, add or remove people (Audiences).

  • People skipped (already in Contacts, with Skip them), rows with problems and rows that could not be saved are not on it.
  • The date is the day the import finished. Import the same file again on the same day and its people join the same list; on another day you get a new list.
  • A cancelled import gets no list. The people it had already imported keep the import's tag, so you can still find them.
  • A workspace keeps up to 500 audiences. When it already has 500, the import finishes without a list and says No list was made for this import: the workspace already keeps 500 audiences. Archive lists you no longer need on Contacts → Audiences; the tag still marks everyone from the file.

How people are matched (no duplicates)

  • A row is the same person as a contact when its phone number (after it is written as +country code and number) or its email is already in this workspace, on any channel. A merged contact is updated as one person.
  • Two rows with the same number or email in one file become one contact: the first creates it, the later ones update it (or are skipped when you chose Skip them).
  • A new contact with a phone number is created as that person's WhatsApp contact, so when they write to you their messages arrive on the same card. Its Source is Import.
  • Every imported contact gets the import's own tag, import: plus the date and file name (for example import:2026-09-24-customers-3f9a), so you can find them again on the Contacts page (filter by the tag), besides the import's list above.

Consent: what is recorded

  • With Yes, each person gets a consent record per ticked channel, with the source Import and your statement, the place, the date and the file name as the evidence, and who started the import. It shows under Consent history on the contact (Consent and opt-out).
  • Only channels the row has an address for: WhatsApp and SMS need a phone number, email needs an email.
  • A Marketing consent (yes / no) column in the file: only rows that say yes (yes, y, 1, نعم, موافق) get consent; rows that say no or are empty get none. Such a column needs the declaration (Yes) or must be set to Don't import.
  • People who withdrew or replied STOP keep their choice (counted as Kept their earlier no). An import never overrides it; only the person, or a teammate recording their new agreement with Record consent, can.
  • With No, nobody gets marketing consent. They can still receive replies in the 24-hour window and utility messages.

If something goes wrong

  • This is an old Excel file (.xls)... → save it as .xlsx or CSV UTF-8 and upload again.
  • The first row must name the columns → add a header row. The file has column names but no rows of people. → the file has a header row and nothing under it (or only empty rows); add one row per person under the column names and upload it again. The file is empty. means nothing at all was found in the file.
  • The file has more than 100,000 rows or The file is larger than 20 MB → split it. The second message also appears for a file that is small but holds millions of filled cells once opened.
  • The file has more than 200 columns. → delete the columns you do not need. A value typed far to the right, even in an otherwise empty column, counts; empty cells do not.
  • Map a phone or an email column. → set one column to Phone (WhatsApp) or Email.
  • Two columns are set to "…" → set one of them to Don't import.
  • Rows in errors.csv, with the reason: Not a valid phone number (check the country code) (check Country for local numbers), No phone number or email, Not a valid email address, Unknown country, Unknown language, Unknown time zone, A custom field value does not fit the field (the field is named in the detail: a choice must be one of its options, a date YYYY-MM-DD or day/month/year, a number digits only), The consent column must say yes or no, Already a contact - skipped, Could not be saved (try importing that row again). errors.csv has the file's own columns, so you can fix the rows and import them as a new file. It comes in the language you use the app in: its first four columns (row, status, reason, detail), the status of each row and the reason are in that language.
  • Cancel import stops before the next 1,000 rows; contacts already imported stay.
  • The rows and the stored copy of the file are deleted 30 days after the upload; then errors.csv is no longer available (The rows of this file were deleted 30 days after the upload.). The import's totals and the consent declaration are kept.

Add one contact

  1. On Contacts press Add contact.
  2. Fill Name (up to 120 characters) and at least one of Phone (WhatsApp) (with the country code, or a local number of the Country you pick), Email, or Handle on another platform with its Platform. Country starts as your company's country (Settings → Company) and lists every country, named in your language; with none set it reads Choose a country. Digits typed on an Arabic keyboard (٠٥٥…) become 0-9 in Phone (WhatsApp) as you type, so the number reads left to right in its usual order.
  3. Optional: Tags (separated by commas), Notes, and under Marketing consent (optional) the channels the person agreed to plus How did they agree?
  4. Press Add contact. You see [name] was added. and the contact opens.
  5. This person is already in Contacts. → the number or email belongs to someone; press Open the contact. When one box is the problem, the reason appears in red under that box, the box turns red and the cursor moves into it. For example That is not a valid phone number for the country chosen. Enter a local number of that country, or the full number starting with + and the country code. under Phone (WhatsApp) (with no Country chosen: That is not a valid phone number. Check the digits after the + and the country code, or choose the Country below and enter a local number.), Choose the platform of the handle. under Platform (whenever a handle is typed, even with a phone or an email), WhatsApp or SMS consent needs a phone number. Enter the number, or untick WhatsApp and SMS. under Phone (WhatsApp), Email consent needs an email address. Enter the address, or untick Email. or Enter an email address like name@example.com. under Email, or Say how the person agreed (at least 3 characters). under How did they agree? Every reason is in your language. Fix it and press Add contact again. A message about the form as a whole (Give a phone number, an email or a handle.) appears at the bottom.

A contact added by a handle only gets its own card; when the person writes to you from that platform, merge the two with Merge with… (Contacts).

Developers (API)

POST /workspaces/{workspaceId}/contacts adds one contact (name, phone, email, handle + platform, country, tags, notes, attributes, consent: {channels, evidence}); 409 returns the existing contactId. Imports: POST .../contacts/imports (multipart file), GET .../contacts/imports/{id}, PATCH {mapping, options}, POST .../validate, POST .../run, POST .../cancel, GET .../errors.csv?lang=ar (lang: en, ar, fr, es, pt, de, tr, id, hi or ur). A finished import's GET returns audience (id, name, memberCount) — the list above.

Related

Checked against the product on Oct 14, 2026

In this section: Engage

All articles