Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
233 lines
7.8 KiB
Plaintext
233 lines
7.8 KiB
Plaintext
---
|
|
title: Import Contacts via CSV
|
|
description: Complete step-by-step guide to importing people/contacts into Twenty.
|
|
---
|
|
|
|
## Overview
|
|
|
|
This guide walks you through importing your contacts (People) into Twenty.
|
|
|
|
## Before You Start
|
|
|
|
### Prerequisites Checklist
|
|
<Check>
|
|
Your file is CSV, XLSX, or XLS format
|
|
</Check>
|
|
<Check>
|
|
File has fewer than 10,000 records
|
|
</Check>
|
|
<Check>
|
|
No duplicate email addresses in your file
|
|
</Check>
|
|
<Check>
|
|
**Companies imported first** (if linking People to Companies)
|
|
</Check>
|
|
<Check>
|
|
All custom fields exist in **Settings → Data Model**
|
|
</Check>
|
|
|
|
<Warning>
|
|
**Import Companies Before People**
|
|
|
|
If you want to link People to Companies, import Companies first. The Company must exist before you can reference it.
|
|
</Warning>
|
|
|
|
## Step 1: Prepare Your Contact Data
|
|
|
|
### Required and Recommended Fields
|
|
|
|
| Field | Required? | Format | Notes |
|
|
|-------|-----------|--------|-------|
|
|
| **Email** | Recommended | `name@domain.com` | Must be unique |
|
|
| **First Name** | Recommended | Text | |
|
|
| **Last Name** | Recommended | Text | |
|
|
| **Company** | Optional | Domain or ID | Links to existing Company |
|
|
| **Phone** | Optional | Multiple columns | See below |
|
|
| **Job Title** | Optional | Text | |
|
|
| **Custom fields** | Optional | Varies | Must exist in Data Model |
|
|
|
|
### Email Format
|
|
|
|
- Must be valid email format: `name@domain.com`
|
|
- **Must be unique** — no duplicates in your file or in Twenty
|
|
- For additional emails, use the **Emails / Additional Emails** column:
|
|
```
|
|
["jane@twenty.com","jane.doe@twenty.com"]
|
|
```
|
|
|
|
### Phone Format
|
|
|
|
Phone is a **nested field** requiring multiple columns:
|
|
|
|
| Column | Example |
|
|
|--------|---------|
|
|
| **Phones / Primary Phone Number** | `4159095555` |
|
|
| **Phones / Primary Phone Country Code** | `US` |
|
|
| **Phones / Primary Phone Calling Code** | `+1` |
|
|
|
|
### Linking to Companies
|
|
|
|
Add a column with the Company's unique identifier:
|
|
|
|
| Column Name | Format | Example |
|
|
|-------------|--------|---------|
|
|
| `companyDomain` | URL format | `https://acme.com` |
|
|
| `companyId` | UUID | `c776ee49-f608-4a77-8cc8-6fe96ae1e43f` |
|
|
|
|
<Note>
|
|
**Use Domain URL format** (`https://acme.com`), not the label. This matches how Companies are stored in Twenty.
|
|
</Note>
|
|
|
|
### Sample CSV Structure
|
|
|
|
```csv
|
|
firstName,lastName,email,jobTitle,companyDomain,Phones / Primary Phone Number,Phones / Primary Phone Country Code
|
|
John,Smith,john@acme.com,CEO,https://acme.com,4159095555,US
|
|
Jane,Doe,jane@widgets.co,CTO,https://widgets.co,2125551234,US
|
|
```
|
|
|
|
<Note>
|
|
**Pro tip:** Click **Download sample file** during import or export a few existing People to see the exact column names Twenty expects.
|
|
</Note>
|
|
|
|
## Step 2: Access the Import Feature
|
|
|
|
**Option 1: From the People View**
|
|
1. Navigate to **People** in the left sidebar
|
|
2. Click the **⋮** icon on the top right
|
|
3. Select **Import records**
|
|
|
|
**Option 2: Using Command Menu**
|
|
1. Press `Cmd + K` (Mac) or `Ctrl + K` (Windows)
|
|
2. Type "import"
|
|
3. Select **Import records**
|
|
4. Choose **People**
|
|
|
|
## Step 3: Upload Your File
|
|
|
|
1. Click **Select file**
|
|
2. Choose your CSV, XLSX, or XLS file
|
|
3. Wait for Twenty to analyze your file
|
|
|
|
## Step 4: Map Your Columns
|
|
|
|
Twenty automatically tries to match your columns to fields. Review and adjust:
|
|
|
|
1. **Check automatic mappings** — verify they're correct
|
|
2. **Fix incorrect mappings** — click the dropdown to select the right field
|
|
3. **Skip columns** — select **Do not map** for columns you don't want to import
|
|
|
|
### Important Mapping Rules
|
|
|
|
| Column Type | Map To | Notes |
|
|
|-------------|--------|-------|
|
|
| Company reference | **Company** relation field | Use domain OR id, not both |
|
|
| Email | **Email** | Primary email address |
|
|
| Additional emails | **Emails / Additional Emails** | Array format |
|
|
| Phone | Separate columns | Number, Country Code, Calling Code |
|
|
|
|
<img src="/images/user-guide/import-export-data/match-columns.png" style={{width:'100%'}}/>
|
|
|
|
### Mapping the Company Relation
|
|
|
|
When mapping the company column:
|
|
1. Find your company reference column (e.g., `companyDomain`)
|
|
2. Map it to the **Company** relation field
|
|
3. Twenty will link each Person to the matching Company
|
|
|
|
<Warning>
|
|
**Map only ONE unique identifier for relations.**
|
|
|
|
Don't map both `companyId` AND `companyDomain`. Choose one—preferably domain since it's human-readable.
|
|
</Warning>
|
|
|
|
## Step 5: Map Select Field Values
|
|
|
|
If you have Select or Multi-Select fields (like Lead Source):
|
|
|
|
1. Twenty shows your values alongside existing options
|
|
2. Match each value in your file to a Twenty option
|
|
3. Or create new options if needed
|
|
|
|
<Note>
|
|
Select options use **API names**, not display labels. Check **Settings → Data Model** → Enable **Advanced mode** to see API names.
|
|
</Note>
|
|
|
|
## Step 6: Review and Fix Errors
|
|
|
|
Before completing the import, Twenty validates your data:
|
|
|
|
1. Click **Next Steps**
|
|
2. Rows with errors are highlighted in **yellow**
|
|
3. **Fix errors directly** — click a cell and edit the value
|
|
4. **Remove problematic rows** — click the X to skip that row
|
|
|
|
### Common Contact Import Errors
|
|
|
|
| Error | Cause | Solution |
|
|
|-------|-------|----------|
|
|
| **Duplicate email** | Email already exists in Twenty or file | Remove duplicate or update existing record |
|
|
| **Invalid email format** | Email format incorrect | Fix to `name@domain.com` |
|
|
| **Relation not found** | Company doesn't exist | Import Companies first or fix the reference |
|
|
| **Missing required field** | Required field is empty | Fill in the value or remove the row |
|
|
|
|
## Step 7: Complete the Import
|
|
|
|
1. Review the import summary
|
|
2. Click **Confirm** to import
|
|
3. Wait for the import to complete
|
|
4. Verify by checking a few records and their Company links
|
|
|
|
## After Importing Contacts
|
|
|
|
Your contacts are now in Twenty! Next steps:
|
|
|
|
1. **Verify Company links** — open a few People records to confirm they're linked to the right Company
|
|
2. **Import Opportunities** — if needed, link them to People and Companies
|
|
3. **Set up email sync** — connect your mailbox to see email history on contact records
|
|
|
|
## Updating Existing Contacts
|
|
|
|
To update contacts instead of creating new ones:
|
|
|
|
1. Include the `email` or `id` column in your file
|
|
2. Twenty matches records by this unique identifier
|
|
3. Existing contacts are updated; new ones are created
|
|
|
|
See [How to Update Existing Records](/user-guide/data-migration/how-tos/update-existing-records-via-import) for details.
|
|
|
|
## FAQ
|
|
|
|
<AccordionGroup>
|
|
<Accordion title="Why can't two People have the same email?">
|
|
Email is a unique identifier in Twenty. This prevents duplicate contacts and ensures email sync correctly links emails to the right person.
|
|
</Accordion>
|
|
|
|
<Accordion title="What if I have people without an email?">
|
|
You can leave the email empty. However, we recommend adding emails when possible for better data quality and email sync functionality.
|
|
</Accordion>
|
|
|
|
<Accordion title="How do I link People to Companies during import?">
|
|
Add a column with the Company's domain (e.g., `https://acme.com`) or ID. During mapping, connect this column to the Company relation field.
|
|
</Accordion>
|
|
|
|
<Accordion title="What if the Company doesn't exist yet?">
|
|
Import Companies first, then import People. The Company must exist before you can reference it.
|
|
</Accordion>
|
|
|
|
<Accordion title="Can I import the ID from my previous CRM?">
|
|
Yes! Create a custom field marked as "unique" in your data model to store the external ID. Note: the field name `id` is reserved for Twenty's internal ID.
|
|
</Accordion>
|
|
|
|
<Accordion title="How do I fix 'relation not found' errors?">
|
|
The Company you're referencing doesn't exist. Either import the Company first, or check that the domain/ID exactly matches an existing Company.
|
|
</Accordion>
|
|
</AccordionGroup>
|
|
|
|
## Troubleshooting
|
|
|
|
Having issues? Check:
|
|
- [How to Fix Import Errors](/user-guide/data-migration/how-tos/fix-import-errors)
|
|
- [How to Import Relations](/user-guide/data-migration/how-tos/import-relations-between-objects-via-csv)
|
|
- [Field Mapping Reference](/user-guide/data-migration/capabilities/field-mapping)
|