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:
| Column | Required | Description |
|---|---|---|
email | Yes | The contact's email address. Rows without a valid email are skipped. |
first_name | No | First name. |
last_name | No | Last name. |
phone | No | Phone number. |
birth_month | No | Birthday month as a number (1–12). Must be paired with birth_day. |
birth_day | No | Birthday day as a number (1–31). Must be paired with birth_month. |
tag1 | No | A tag to assign to this contact. |
tag2 | No | A second tag. |
tag3 | No | A third tag. |
note1 | No | A note to attach to the contact record. |
note2 | No | A second note. |
note3 | No | A third note. |
Import Options
When initiating an import, you can configure:
| Option | Description |
|---|---|
| Global Tag | A single tag to apply to every contact in the batch. Useful for tagging a segment like "2024 Conference Attendees". |
| Mark as Subscribed | If 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_monthwithoutbirth_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,