Contacts & Tags
CSV Import

CSV Import

Gordon CRM provides a powerful bulk import pipeline that lets you upload contacts from a CSV file. The import runs as a single atomic database transaction — if anything fails, everything rolls back cleanly.

Supported Columns

Your CSV file can include any of the following column headers:

ColumnRequiredDescription
emailYesThe contact's email address. Rows without a valid email are skipped.
first_nameNoFirst name.
last_nameNoLast name.
phoneNoPhone number.
birth_monthNoBirthday month as a number (1–12). Must be paired with birth_day.
birth_dayNoBirthday day as a number (1–31). Must be paired with birth_month.
tag1NoA tag to assign to this contact.
tag2NoA second tag.
tag3NoA third tag.
note1NoA note to attach to the contact record.
note2NoA second note.
note3NoA third note.

Import Options

When initiating an import, you can configure:

OptionDescription
Global TagA single tag to apply to every contact in the batch. Useful for tagging a segment like "2024 Conference Attendees".
Mark as SubscribedIf enabled, all imported contacts will have is_subscribed set to true with a full proof-of-consent record (timestamp, source = "CSV Import", uploader IP).

How Upsert Works

The import uses an upsert strategy keyed on workspace_id + email:

  • New contacts are inserted with all provided fields.
  • Existing contacts are updated — but only non-empty fields are overwritten. Blank CSV columns will not erase existing data.

Subscription Behavior on Upsert

  • If "Mark as Subscribed" is enabled and the contact is already subscribed, the original consent proof is preserved (not overwritten).
  • If "Mark as Subscribed" is enabled and the contact is not yet subscribed, new consent proof is recorded.
  • If "Mark as Subscribed" is disabled, existing subscription status is never changed.

Birthday Validation

Gordon CRM enforces "all-or-nothing" birthday rules to prevent partial data:

  • If you provide birth_month without birth_day (or vice versa), the birthday is skipped and an error is logged for that row.
  • Valid ranges: month 1–12, day 1–31.
  • Invalid values (non-numeric, out of range) are skipped with a per-row error; the rest of the contact's data is still imported.

Tag Handling

  • Tags are created automatically if they don't already exist.
  • Tag matching is case-insensitive — importing "vip" when "VIP" already exists will link to the existing tag.
  • The first-seen casing wins for new tags created during import.
  • Up to 3 per-row tags plus 1 global tag can be assigned per contact.

Error Handling

The import pipeline does not fail on individual row errors. Instead:

  • Invalid rows (missing email, bad email format, invalid birthday) are skipped.
  • A detailed error report is returned listing the row number and reason for each skip.
  • All valid rows are still processed successfully.

If a catastrophic error occurs (database failure, etc.), the entire transaction rolls back — no partial data is committed.

Example CSV

email,first_name,last_name,phone,birth_month,birth_day,tag1,tag2,note1
jane@example.com,Jane,Doe,555-0101,3,15,VIP,Newsletter,Met at conference 2024
john@example.com,John,Smith,555-0102,,,Lead,,Referred by Jane
admin@acme.com,Admin,User,,,,Enterprise,Key Account,