Campaigns & outbound

Importing an audience from a CSV

Upload a resident list into a Manual segment: map exactly one column to a resident key, an optional language column, and everything else becomes a merge field.

By The Kav team Published 2 min read

A campaign sends to a segment, and a Manual segment's members come from a CSV you import here — three steps, in order: pick the target, attach the file, map its columns.

Step 1 — target and default language

Choose which Manual segment this import adds to, and a default language code (e.g. he) for any row that doesn't specify its own.

Step 2 — attach the file

The file is read only to show you its header row and a short preview of the first few rows. The actual import sends your file's raw bytes to the server unchanged — nothing is re-serialized client-side, specifically so nothing about how your spreadsheet software quoted a field or encoded a comma can drift between what you see in the preview and what the server actually parses.

Step 3 — map every column

Each column gets one of four roles:

  • Skip — ignored entirely.
  • Resident key — required, and required exactly once. This is the identifier the rest of the platform uses to recognize this resident everywhere else; import can't proceed without it.
  • Language — optional, overrides the default language for that row.
  • Attribute — everything else. Give it a name (letters, digits and underscores only) and it becomes a merge field your message templates can reference as {{ name }}.

The import button stays disabled until exactly one column is mapped to resident key. Two columns mapped to it, or zero, both block the import — this isn't a soft warning.

After you import

A summary shows the total rows read, how many imported successfully, how many were rejected, and the segment's new total size. A handful of sample rejected rows are shown with their reason — a row missing its resident key value is the one reason this screen currently translates into a full sentence; any other rejection code is still shown, just as the raw code, rather than being silently dropped.

Re-running an import into the same segment adds to it — it doesn't replace what's already there. Remove members you no longer want from the segment's own detail screen rather than expecting a re-import to clear them.